diff --git a/docs/std_corpus_2026-05.md b/docs/std_corpus_2026-05.md new file mode 100644 index 0000000..4091906 --- /dev/null +++ b/docs/std_corpus_2026-05.md @@ -0,0 +1,144 @@ +# oshwhub Std corpus 交付(2026-05 快照) + +**快照时间**:2026-05-03 +**数据源**:oshwhub.com(origin=std) +**用途**:研究用,不再分发;下游同学批量接入 EPRO2/Std → KiCad / Wokwi pipeline + +--- + +## 总览 + +| 项 | 值 | +|---|---:| +| oshwhub Std 项目总数(origin=std) | **12,493** | +| 含完整可编辑器源工程 | **12,166(97.4%)** | +| 仅 metadata + 附件(upstream 没编辑器 session) | 327(2.6%) | +| sch + pcb doc 总数(多页累加) | **30,488** | +| 源工程文件体积(`.json` 解码后) | 11.79 GB | +| 上游 listing pool 覆盖率 | 12,493 / 12,493 = **100%** | + +--- + +## 按批次 + +| 批次 | 项目数 | 有源 | attach_only | docs | 选取规则 | +|---|---:|---:|---:|---:|---| +| `batch_early_std` | 112 | 108 | 4 | 427 | 早期混抓(Pro 同期顺手抓的 std)| +| `batch1000_std` | 1,000 | 963 | 37 | 2,853 | A 档头部,like p50=43 | +| `batch4000_std` | 4,000 | 3,884 | 116 | 10,100 | A 档剩余 + B + C 头 | +| `batch_remaining_a_std` | 3,691 | 3,641 | 50 | 8,877 | rank 中段 | +| `batch_remaining_b_std` | 3,690 | 3,570 | 120 | 8,231 | 长尾(grade 0/1)| +| **合计** | **12,493** | **12,166** | **327** | **30,488** | | + +--- + +## License 分布(top 12) + +| 数 | 占比 | License | +|---:|---:|---| +| 7,050 | 56.4% | GPL 3.0 | +| 2,384 | 19.1% | Public Domain | +| 543 | 4.3% | CC-BY-NC-SA 3.0 | +| 507 | 4.1% | unknown | +| 377 | 3.0% | MIT | +| 156 | 1.2% | MIT License(同 MIT,立创平台没归一)| +| 147 | 1.2% | CC BY-NC-SA 4.0 | +| 147 | 1.2% | BSD | +| 144 | 1.2% | CERN Open Hardware License | +| 140 | 1.1% | LGPL 3.0 | +| 136 | 1.1% | CC-BY-NC 3.0 | +| 132 | 1.1% | CC BY-NC-SA 3.0 | +| 630 | 5.0% | 其它 21 种(含 TAPR / CC BY / CC0 / null …)| + +> 下游做 license 归一化白名单时,正向许可可见 6 类:MIT / BSD / Apache / CC0 / CC-BY / Public Domain。注意 license 字段保留原始字符串,未做归一化("MIT" 与 "MIT License" 视为不同 key)。 + +--- + +## EasyEDA Std editor 版本(top 10,含源工程的 12,166 项里统计) + +| 数 | 占比 | 版本 | +|---:|---:|---| +| 1,192 | 9.8% | 6.4.25 | +| 906 | 7.4% | 6.4.7 | +| 678 | 5.6% | 6.5.5 | +| 564 | 4.6% | 6.5.15 | +| 535 | 4.4% | 6.5.22 | +| 447 | 3.7% | 6.4.20.6 | +| 403 | 3.3% | 6.5.1 | +| 355 | 2.9% | 6.5.23 | +| 350 | 2.9% | 6.5.34 | +| 327 | 2.7% | 6.5.28 | + +剩余分布在 6.3.x ~ 6.5.4x 全谱系。下游 parser 按 6.4.x / 6.5.x 主版本分支处理即可。 + +--- + +## 数据交付 + +### 双桶副本(腾讯云 COS) + +| Region | Bucket | +|---|---| +| ap-guangzhou | `facere-gz-1321068335` | +| ap-singapore | `facere-1321068335` | + +### Singapore 区直链下载(30 天有效,2026-06-02 过期) + +| 对象 key | 大小 | 项目数 | 直链 | +|---|---:|---:|---| +| `batch_early_std.zip` | 93 MB | 112 | [download](https://facere-1321068335.cos.ap-singapore.myqcloud.com/batch_early_std.zip?q-sign-algorithm=sha1&q-ak=AKID6HF1bx6A3jCSXP3UjneIjwwj7JJ8kANN&q-sign-time=1777776835%3B1780368895&q-key-time=1777776835%3B1780368895&q-header-list=host&q-url-param-list=&q-signature=09bf61ec57fbe8d758397c73d981faff47e1086e) | +| `batch1000_std.zip` | 471 MB | 1,000 | [download](https://facere-1321068335.cos.ap-singapore.myqcloud.com/batch1000_std.zip?q-sign-algorithm=sha1&q-ak=AKID6HF1bx6A3jCSXP3UjneIjwwj7JJ8kANN&q-sign-time=1777776835%3B1780368895&q-key-time=1777776835%3B1780368895&q-header-list=host&q-url-param-list=&q-signature=fd003a27c831c0c0337615b36e7f697159f4f83e) | +| `batch4000_std.zip` | 1,378 MB | 4,000 | [download](https://facere-1321068335.cos.ap-singapore.myqcloud.com/batch4000_std.zip?q-sign-algorithm=sha1&q-ak=AKID6HF1bx6A3jCSXP3UjneIjwwj7JJ8kANN&q-sign-time=1777776835%3B1780368895&q-key-time=1777776835%3B1780368895&q-header-list=host&q-url-param-list=&q-signature=427b5f15f2888f630c91b5ca5e0107b2d6b15c4c) | +| `batch_remaining_a.zip` | 1,065 MB | 3,691 | [download](https://facere-1321068335.cos.ap-singapore.myqcloud.com/batch_remaining_a.zip?q-sign-algorithm=sha1&q-ak=AKID6HF1bx6A3jCSXP3UjneIjwwj7JJ8kANN&q-sign-time=1777776835%3B1780368895&q-key-time=1777776835%3B1780368895&q-header-list=host&q-url-param-list=&q-signature=9fa2744d879bd17842129396b2656cb1f56ae81b) | +| `batch_remaining_b.zip` | 891 MB | 3,690 | [download](https://facere-1321068335.cos.ap-singapore.myqcloud.com/batch_remaining_b.zip?q-sign-algorithm=sha1&q-ak=AKID6HF1bx6A3jCSXP3UjneIjwwj7JJ8kANN&q-sign-time=1777776835%3B1780368895&q-key-time=1777776835%3B1780368895&q-header-list=host&q-url-param-list=&q-signature=f5cfa3b6010ac2fd81df36c61e64e9da2d68d8fa) | +| **合计** | **3,898 MB** | **12,493** | | + +直链特性: +- presigned URL,30 天有效(到 **2026-06-02 ~17:14 UTC** 失效) +- URL 内嵌 `q-ak`(COS access key id,公开标识,不是密钥),不含 SecretKey +- 任何能访问公网的机器 `wget` / `curl -O` 即可 +- 失效后联系我重新签发;URL 本身不可续期 + +下载示例: +```bash +wget -O batch1000_std.zip 'https://facere-1321068335.cos.ap-singapore.myqcloud.com/batch1000_std.zip?...' +``` + +或用 coscmd(需要凭据): +```bash +coscmd download batch1000_std.zip ./batch1000_std.zip +``` + +--- + +## 解压后单项目目录结构 + +每个 zip 解开后落到 `data/raw/oshwhub//`: + +``` +data/raw/oshwhub// +├── metadata.json # 统一 schema,见 schemas/project.schema.json +├── description.md # 标题 + 简介 + license +├── cover.{jpg,png} # 封面图(如果上游有) +├── _urls.json # 原始 URL 集合 +└── source/ # EasyEDA Std 源工程(含完整源的项目才有) + ├── .json + ├── .json + └── ... +``` + +`source/*.json` 是 EasyEDA Std API 返回的 dataStr: +- `result.docType` = 1(schematic)/ 3(PCB)/ 2(symbol library) +- `result.dataStr.shape[]` = `VERB~field1~field2~...` 串数组(LIB / W / N / TRACK / VIA / COPPERAREA …) +- `result.dataStr.canvas` / `layers` / `head`(含 editorVersion) + +下游 EPRO2/Std → KiCad / Wokwi 适配代码已经在 `tools/epro2/std/` 走通,参考 `docs/sources/epro2_to_std_mapping.md` 看字段映射。 + +--- + +## 注意事项 + +- **327 项 attach_only**:upstream API 返空 `documents`,多为早期纯 PCB 上传 / 项目废弃;保留了 metadata + 附件 URL,没有可编辑器源 +- **license 未归一化**:保留 oshwhub 原始字段值;下游做白名单过滤时注意大小写 / 空格 / 同义词(如 "MIT" vs "MIT License" vs "mit") +- **小批次(< 100 项)抽样验证**:建议下游先抽 `batch1000_std.zip` 跑通解析 pipeline,确认无误再吃全量 +- **重新签发 URL**:临时脚本 `/tmp/gen_urls.py`(dev1 + SG box 都有),改 `TTL` 后重跑 diff --git a/log.md b/log.md index 9cc0974..296c2d8 100644 --- a/log.md +++ b/log.md @@ -4,6 +4,177 @@ --- +## 2026-05-03 07:17 batch-remaining-std:扫完所有未抓 std 项目(7,381),双桶副本 + +**Claude 会话** + +收尾批:把 unfetched std 池子(7,381 项)一次扫完。拆 A/B 两批 ~3690 each,按 rank 50/50 切(A 头部、B 长尾),**取消单作者上限 2**(这是 sweep 全量,不需要再做多样性约束)。两批走完整 1-4 步 + zip + 双桶推送。 + +### 候选筛选 +- A:top 3691 by rank(grade 0-4 都有,likes p50=8 / p90=29 / max=275) +- B:bottom 3690(几乎全 grade 0/1,likes p50=1 / p90=4 / max=21) +- 候选 jsonl:`data/state/oshwhub_remaining_{a,b}_std_candidates.jsonl` + +### 第一轮 driver bug 全军覆没(必读) +**症状**:driver 跑了 26 min "顺利完成",但所有 7,381 项 source 都 0——`source_documents=[]` 全空。两个 zip 才 7 MB / 6.8 MB(只 metadata + description,没 source)。 + +**根因**:driver 里 Step 4 用 `python3 - < /tmp/step_X.py <` 选项替代 `--uuids` 字符串,下次大批量不用绕路写 driver 内嵌 Python(参考 `/tmp/backfill_4000.py` 模式可以直接搬进 crawler) +- driver 模板加 sanity check:跑完每个 batch 用 `du -sh /tmp/${SHORT}.zip` 与 raw bytes 比,如果压缩比 < 5% 报警(这次的 7 MB zip 用这个能立即抓到) +- 全 std corpus 已落地,下次扩量目标应该是 Pro 项目(93 项飞控 Pro 候选还没动)或扩到 oshwhub 之外站点 + +--- + +## 2026-05-03 03:58 batch-4000-std:Step 1-4 + zip + COS 链路落地 SG box + +**Claude 会话** + +接 batch-1000-std。再扩 4000 项 std → corpus 142 → 1142 → 5142。本批走完整 1-4 步,zip 后通过 COS 跨区链路拉到 SG box 本地(绕开 dev1↔SG 公网丢包链路)。 + +### 候选筛选 +- 数据源同上 +- A 档(grade≥3 & like≥10)剩 396 项不够 4000,下沉到 unfetched 全池 11,381 按 rank score 倒排,单作者 ≤ 2,取前 4000 +- 候选 jsonl 落 dev1 `data/state/oshwhub_batch4000_std_candidates.jsonl` +- 质量分布:grade 4: 16 / 3: 448 / 2: 1798 / 1: 1319 / 0: 419;likes p50=10 / p90=42(A 档第三梯队 + B + C 头部) + +### 抓取(dev1,concurrency=5) +- **Step 1** 详情扫 license:~24 min,3989/4000 OK + 11 fail(全 "Server disconnected"),重抓 concurrency=2 全过 → 4000/4000 metadata +- **Step 2** license 盘点:56% GPL 3.0、20% PD、4.8% MIT、4.8% NC-SA、4.3% unknown(unknown 比例比 batch-1000 高,B/C tier 项目 license 标注更随便) +- **Step 4** std-source backfill:~31 min,3983 OK + 17 fail + - 15 项 "Server disconnected" 瞬态,重抓全过 + - 2 项 upstream 真实问题:1× `404 文档未找到`(doc 被删),1× `code 104001`(项目封)。这 2 项保留 metadata-only +- 最终:4000/4000 metadata · **3998 含完整 sch/pcb 源工程** · 2 metadata-only + +### 关键修:`--uuids` 撞 ARG_MAX +- backfill 路径用 `--uuids "$(jq ... | paste -sd,)"`,4000 UUID × 33B ≈ 132 KB > ARG_MAX (128 KiB) +- 现象:`bash: /usr/bin/nohup: Argument list too long`,进程没启动,但 pgrep 误匹配 stale shell +- 修:临时脚本 `/tmp/backfill_4000.py`,直接 import `crawlers.oshwhub.crawler` 内部函数(`_run_backfill_concurrent` / `fetch_std_source`),UUID 集从 candidates jsonl 读,绕开命令行 +- 长期:crawler 应加 `--backfill-uuids-file ` 选项,下次扩量再改 + +### ZIP 打包(dev1) +- 4000 dirs,26,098 文件,4,489 MB raw → **1,445 MB zip**,压缩比 32.2%,99 秒完成 +- 用 Python `zipfile` + `compresslevel=1`(dev1 没装 `zip` 二进制) + +### 传输链路(COS 三段,0 字节走公网丢包链路) +| 段 | 时长 | 速度 | 路径 | +|---|---:|---:|---| +| dev1 → `facere-gz-1321068335` (ap-guangzhou) | 17s | 166 MB/s | 同区内网 | +| GZ 桶 → `facere-1321068335` (ap-singapore) | 23s | — | COS 服务端 copy(VM 不参与) | +| SG 桶 → SG box | 8.5s | 201 MB/s | 同区内网 | +| **整 1.4 GB 跨地域 ~50 秒** | | | | + +哈希校验穿三段:`a79a87e4a3f5dfbad80d9ba94f557b09010e104f6e0c968ea87eba2267b262b3`。 + +### 决策(Why) +- **rank-score top-4000 不设硬阈值**:硬过滤太挑会漏,rank score 已综合 like\*3 + grade\*50 + views/100 + comments\*2 + fork\*2 + star,自动平衡。最低 like=0 也进了几百项(多数是 grade≥1 但社区互动少的),可接受。 +- **不传统 scp,走 COS 三段**:之前飞控-77 33 MB scp 走 dev1↔SG 6.5%-loss 链路要 3 min;这次 1.4 GB 走 COS 50 s 完事,提速 ~150×。COS 跨区复制流量计费 ~¥0.5/GB × 1.4 GB ≈ ¥0.7,零头。 +- **zip vs tar.gz**:zip 选 level=1,速度 vs 体积平衡;tar.gz 单线程 deflate 跟 zip-l1 体积相近但慢 2-3×。 + +### 完成度 +- corpus 由 1142 项扩到 **5142 项**(+4000) +- License: 56% GPL 3.0 主流不变,unknown 比例从 0.4% (batch-1000) 涨到 4.3% (batch-4000),与 B/C tier 项目低标注度一致 +- editor 版本从 6.3 全谱系到 6.5.42 都覆盖到了 +- 源文件体积:dev1 上 `data/raw/oshwhub/` 占 ~10 GB(含全部历史 + 本批) + +### 下一步建议 +- corpus 已经达 5142 项,足够下游 EPRO2/Std → KiCad 训练数据规模 +- 真要继续扩,A+B+C 档已基本吃完头部,下沉 D 档(grade=0 或 like=0)质量回报递减,可暂缓 +- crawler 加 `--backfill-uuids-file` 选项,避免下次 ARG_MAX 撞墙 +- COS GZ 桶里的 `batch1000_std.zip` + `batch4000_std.zip` 用完可以删(SG 桶副本足够),节省 ~¥0.2/月 存储费 + +--- + +## 2026-05-03 batch-1000-std:Step 1-4,1000 块标准板源工程入库(dev1) + +**Claude 会话** + +走 batch-200 脚手架抓 1000 项 std A 档剩量。**用户指令"只走 1-4 步"**:不抓附件、不传 SG、不 push gitea,数据留 dev1。 + +### 候选筛选 +- 数据源:`data/state/oshwhub_listing_full.jsonl`(33,695 项) +- 过滤:`origin=std AND grade≥3 AND like≥10`(A 档),减去已抓 142 项 → 池子 1,396 项 +- 排序:rank score 倒序;单作者 ≤ 2 → 取前 1000(791 唯一作者) +- 候选 jsonl 落 dev1 `data/state/oshwhub_batch1000_std_candidates.jsonl`(不入 git,可重算) +- like p50=43 / p90=170 / max=420(A 档第三梯队,吃掉 1,396 池子的 ~72%) + +### 抓取(dev1 Guangzhou,concurrency=5) +- **Step 1** 详情扫 license:~80s,996/1000 OK + 4 "Server disconnected" 瞬态 fail +- 4 项重抓 (concurrency=2) 全 OK → 1000/1000 metadata +- **Step 2** license 盘点:57% GPL 3.0、19% PD、8.6% CC-BY-NC-SA、5.4% MIT、其它 < 2%。形态与 batch-50 / batch-200 一致。 +- **Step 3** SKIP:本批 std-only,没有 Pro 候选 +- **Step 4** std-source backfill:~6 分钟,1000/1000 OK,0 fail + +### 完成度 +- 1000/1000 metadata +- 963 项有完整 std 源工程(2,853 个 sch+pcb doc,平均 2.96 docs/proj) +- 37 项 upstream attachments-only(`source_documents=[]` 真实状态,跟飞控-77 4/77 同形态) +- 源文件体积:1.47 GB on dev1(按 batch-50 估算 12 MB/项 偏高,实测 1.5 MB/项——A 档第三梯队项目体量比头部小) +- editor 版本:194 项 6.4.25 / 91 项 6.5.5 / 77 项 6.5.1,6.4-6.5 全谱系覆盖 +- corpus 由 142 项扩到 1,142 项(+1000) + +### 决策(Why) +- **不传 SG / 不 push gitea**:用户指明只走 1-4 步。数据 1.47 GB 走 dev1↔SG 6.5%-loss link 估 ~3 hr 单 scp,没必要现在花。要传时再走 COS 跨区或 split-parallel-scp。 +- **concurrency=5 全程**:飞控-77 验证过 std doc endpoint 这个并发安全;实测 Step 1 ~12s/100项、Step 4 ~36s/100项,零限流告警。 +- **Step 3 跳过**:候选池纯 std-origin,Pro backfill 没数据可处理。 + +### 下一步建议 +- 真要消费这批数据:(a) 在 dev1 直接 push gitea(SSH transport,~10 min @ 1.5 GB),或 (b) 走 COS 跨区同步到 SG。 +- 该批的 metadata-only 部分(37 项 attachments-only)若想补 sch/pcb,需要回头单独扫 attachment ZIP 看里面是否 bundled 了 EasyEDA 工程,那得改 crawler。 +- A 档剩余只有 396 项了;下次再扩可以下沉到 B 档(grade≥2 & like≥5,3,884 项 unfetched)。 + +--- + ## 2026-04-30 19:10 飞控-77:主题定向抓 77 块标准飞控板 **Claude 会话**