Files
FacereDataset/docs/plans/oshwhub_batch200.md
Knowit 7cb35020f4 plan: batch-200 expansion (100 Pro + 100 Std)
Doubles down on what worked in batch-50:
  - dev1 (Guangzhou) is primary execution host
  - Owner cap=2 for diversity
  - --max-source-mb 200 to defend against X86-class outliers
  - Pro 2.x deprecated-board fix is already in (commit c3cac97)
  - SSH transport for dev1 -> gitea (commit 8220c99)

Candidate pool:
  200 picks from A-tier (grade>=3 & like>=10) minus already-crawled 65
  Remaining A-tier corpus is 2,741 (Pro 1326 + Std 1415)
  173 unique authors, like median 258, grade dist 4:118 / 3:82

Estimated walltime ~25-35 min on dev1 for Step 1-4 (no attachments).
LFS increment ~2.5 GB (source only) or +10 GB if Step 5 attachments
included. Either way well within Gitea's 200 GB migration threshold.

Step 5 (attachment download) deferred — not on the critical path for
EPRO2/Std → KiCad work, can revisit when license-filtered Forge
projection demands it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 02:29:53 +08:00

7.7 KiB
Raw Blame History

oshwhub 扩抓批 200执行计划

创建2026-04-29 承接docs/plans/oshwhub_batch50.md(已 100% 完结) 目标:从 65 项扩到 265 项 — 验证流水线在中等规模的稳定性,开始覆盖 A 档第二梯队 候选清单data/state/oshwhub_batch200_candidates.jsonl200 行) 主执行机dev1广州~30× 网络优势已实测)


1. batch-50 经验回放(影响这一批的设计)

教训 这一批的对策
dev1 Guangzhou 网络是关键加速器 全部步骤都在 dev1 跑SG 这边只是同步消费
Pro 2.x 占高质量 Pro 池 80% Pro 2.x parser 必须稳deprecated-board 已修
git push 单次 70 MB 在 dev1 → gitea 链路 6.5% 丢包 → 360 KB/s dev1 origin 已切 SSH 协议commit 8220c99),后续 push 流畅
--max-source-mb 200 没触发25 Pro 最大才 9 MB 保留 cap 防 X86-class outlier但预期触发率极低
git push 2>&1 | tail -5 永远 exit 0 吞掉错误 启用 set -o pipefail 或检查 PIPESTATUS
Pro 2.x boards[] 可能含废弃 sch/pcb 返 401 已修:ticket.schematics/pcbs 求交集commit c3cac97
详情 HTML 抓取是 server-render bound~50ms / 项) 不优化;本批 200 项 ~10s 即可

2. 候选池筛选标准(与 batch-50 一致)

数据源:data/state/oshwhub_listing_full.jsonl33,695 项全量索引)

硬过滤

  • grade >= 3 AND like >= 10A 档)
  • uuid 不在已抓 65 项内(剩余 A 档 = 2,741 项 Pro 1326 + Std 1415

排序like*3 + star + fork*2 + views/100 + comments*2 + grade*50

多样性约束

  • 单作者全局上限 2
  • Pro / Std 100:100 均衡(同 batch-50 思路)

3. 选出的 200 项概况

维度
总数 200100 Pro + 100 Std
唯一作者 173max 单作者 2 项)
like 区间 min=22 / median=258 / max=624
grade 分布 4: 118 项, 3: 82 项

like 中位数 258 比 batch-50 的 554 低——因为 batch-50 已经吃掉了 A 档头部。本批进入 A 档第二梯队,整体仍合格。

完整名单见 data/state/oshwhub_batch200_candidates.jsonl


4. 执行步骤

全部在 dev1 跑。SG 端只 git pull 消费成果。

Step 0 — 候选池冻结

oshwhub_batch200_candidates.jsonl 已生成。

Step 1 — 详情页扫 license~3 min @ concurrency=5

ssh dev1 'export PATH=$HOME/.local/bin:$PATH && \
  cd ~/repo/FacereDataset && \
  PYTHONUNBUFFERED=1 uv run python -u -m crawlers.oshwhub \
    --from-jsonl data/state/oshwhub_batch200_candidates.jsonl \
    --no-files --no-cover --concurrency 5 \
    --out data/raw/oshwhub'

预期200 项 / ~3-5 分钟dev1 详情页 p90=73ms × 200/5 并发 ≈ 3s 网络 + server render 时间 ≈ 几分钟)。

Step 2 — license 分布盘点(无过滤入库)

ssh dev1 'cd ~/repo/FacereDataset && uv run python - <<EOF
import json, glob, collections
target = {json.loads(ln)["uuid"] for ln in open("data/state/oshwhub_batch200_candidates.jsonl")}
licenses = collections.Counter()
for p in glob.glob("data/raw/oshwhub/*/metadata.json"):
    m = json.load(open(p))
    if m.get("project_id") in target:
        licenses[m.get("license") or "<unknown>"] += 1
for lic, n in licenses.most_common():
    print(f"  {n:>4}  {lic}")
EOF'

按 batch-50 数据外推:~64% GPL 3.0、~16% Forge-friendly 自由、~16% NC variants。

Step 3 — Pro 100 项 backfill source~10-15 min

ssh dev1 'export PATH=$HOME/.local/bin:$PATH && \
  cd ~/repo/FacereDataset && \
  PRO_UUIDS=$(jq -r "select(.origin==\"pro\") | .uuid" \
                data/state/oshwhub_batch200_candidates.jsonl | paste -sd,) && \
  PYTHONUNBUFFERED=1 uv run python -u -m crawlers.oshwhub \
    --backfill-pro-source \
    --uuids "$PRO_UUIDS" \
    --max-source-mb 200'

预期分布(按 batch-50 的 Pro 比例外推):

  • Pro 2.x legacy ~80 项chain 平均 < 30每项 ~30s → ~40 分钟……

等等得拆估算dev1 端 Pro chain 是 0.5s sleep × N + CDN 0.2s × M。粗算单项 average = 0.5×5 + 0.2×30 = 8.5s。100 项串行 = ~14 min。 如果想再快可以加 backfill 路径的 concurrency目前没加是个小改动。先不优化看实测。

Step 4 — Std 100 项 backfill source~5-10 min

STD_UUIDS=$(jq -r 'select(.origin=="std") | .uuid' \
              data/state/oshwhub_batch200_candidates.jsonl | paste -sd,)
ssh dev1 ... --backfill-source --uuids "$STD_UUIDS"

每项 ~5-10sStd 比 Pro 快doc 数少100 项 ~10 min。

Step 5 — 附件下载(可选 / 推迟

batch-50 的 50 项声明附件 2.36 GB外推 batch-200 ~9-10 GB。Gitea LFS 当前用量 < 5 GB加 10 GB 还在舒适区。

但下载时间是关键因素:

  • 200 项 × 平均 50 MB 附件 / 5 MB/sdev1 → image.lceda.cn 估算)= ~30 分钟
  • --skip-ext mp4,qt,mov 可砍 30-50% 体积

建议:先做 Step 1-4 拿到 license + source附件单独评估后再决定。如果只为 EPRO2 → KiCad 训练,附件不需要。

Step 6 — 验收 + push

ssh dev1 'cd ~/repo/FacereDataset && \
  uv run python scripts/build_index.py && \
  git add data/raw/oshwhub/ projects.md && \
  git commit -m "batch-200: ..." && \
  git push origin main'

5. 资源预算

估算 备注
API 调用 ~2,500 次 200 详情 + 100 Pro × 5 calls + 100 Std × 5 calls + chain blob 几百次
dev1 walltimeStep 1-4 ~25-35 分钟 单 IP 串行;加 backfill concurrency 可压到 10-15 min
源工程体积 ~2.5 GB batch-50 实测 12 MB/项 × 200 = 2.4 GB
Gitea pushdev1 SSH 链路) ~3-5 min 同 batch-50 量级SSH transport 健康
附件(如做 Step 5 +10 GB / +30 min 可砍 mp4 节流
LFS 总增量(不含附件) ~2.5 GB 当前 < 5 GB → batch-200 后 ~7-8 GB
LFS 总增量(含附件) ~12 GB → 批后 ~17 GB离 200 GB 迁移线还远

6. 风险与预案

风险 概率 影响 预案
Pro cookie 过期半路 100 项 Pro 可能多个失败 已在 dev1 + SG 同 cookie过期表现是连续 401监控前 5 个失败即停
单 Pro 项目超 200 MB size cap 触发跳过 --max-source-mb 200 拦截,记 oversize state
Pro 2.x 又出现新边缘 case非 deprecated-board 单项 fail 当前 fix 处理 deprecated 类;新 case 用 try/except 单点收敛后 retry
附件 mp4 视频拉爆磁盘 中(如做 Step 5 多消耗 5+ GB --skip-ext mp4,qt,mov
dev1 → gitea 链路波动期间 push 需手动重试 已切 SSHBBR 已开;最差 retry
触发 oshwhub 限流 整批中断 现有 sleep 已在实测水位;监控 200/non-200 比例,连续 3 个 5xx 即停

7. 验收标准

  • data/raw/oshwhub/ 新增 ≥ 195 个项目目录(允许 ≤ 5 项 fail
  • 每个新增项目的 metadata.jsonlicense + source_format + source_path
  • license 分布盘点写入 log
  • projects.md 自动重建后包含全 265 项
  • LFS 增量 < 5 GB不含附件/ < 15 GB含附件
  • log.md 顶部一条总结性日志
  • dev1 push 整批 ≤ 10 min wall

8. 后续候选

  • batch-500 —— 把 A 档2,741 项)一次性吃完(剩 ~2,540
  • B 档grade≥2 & like≥5扩量 —— 总池子 ~6,243 项
  • 附件细分策略 —— 按 ext 分类 LFSGerber/STEP 留、视频走外链)
  • Pro 2.x → KiCad 解析链路 —— 复用 easyeda2kicad.pyplan.md §1.7 提过但未做)
  • license 详情扫全 A 档 —— 全 2,806 项 license 落本地,给所有未来批选作过滤依据