#!/usr/bin/env bash # 并行生成:bash ml/gen/run_parallel.sh <每进程条数> <进程数> [起始种子=1] ["--consensus 4"] # 例:8 核机器 5 万条 → bash ml/gen/run_parallel.sh 6250 8 # 2026-10-18 第五轮(审查 N-7 / N-16 / 缺口 1): # - 每个种子先写 shard_XXXX.jsonl.part,写完才改名 → 中断/并发都不会留下被截断却看似完整的 shard; # - 已存在的 shard_XXXX.jsonl(写完的)直接跳过;没写完的 .part 由 gen_dataset 从断点续写(只补剩下的条数); # - 逐个 wait 子进程并检查返回码(此前裸 `wait` 恒为 0,某个 node 崩了也会继续统计); # - 每 60 s 往控制台打一行节拍(已写条数 + 各进程最新进度),网页「终端输出」可见。 set -e N=${1:-500}; P=${2:-2}; S0=${3:-1}; EXTRA=${4:-} cd "$(dirname "$0")/../.." mkdir -p ml/data pids=(); seeds=() for ((i=0;i
> ml/data/log_$s.txt && mv "$f.part" "$f" ) & pids+=($!); seeds+=($s) done t0=$(date +%s); tl=$t0 while :; do alive=0; for p in "${pids[@]}"; do kill -0 $p 2>/dev/null && alive=$((alive+1)); done [ $alive = 0 ] && break sleep 5 if [ $(( $(date +%s) - tl )) -ge 60 ]; then tl=$(date +%s) n=$(cat ml/data/shard_*.jsonl.part 2>/dev/null | wc -l) last=$(for s in "${seeds[@]}"; do tail -n1 ml/data/log_$s.txt 2>/dev/null; done | head -n 2 | tr '\n' ' ') echo "[gen 节拍] $(( (tl-t0)/60 )) 分钟 运行中 $alive/${#pids[@]} 进程 本批已写 $n 条 $last" fi done fail=0 for k in "${!pids[@]}"; do if ! wait ${pids[$k]}; then echo "[gen] 种子 ${seeds[$k]} 失败,最后几行:"; tail -n 5 ml/data/log_${seeds[$k]}.txt || true; fail=1; fi done [ $fail = 0 ] || exit 6 node ml/gen/stats.cjs ml/data/shard_*.jsonl > ml/data/stats.json cat ml/data/stats.json