每日数据飞轮运行说明
可选扩展:小模型精炼插件提供默认关闭的附加 CPT 分支,统一 .env 配置,支持 audit/apply 和独立重写开关。
本页目录
实现入口:workflow.flywheel_cli。流程是来源发现 → 持久队列 → 下载与 PDF 校验 → OCR → 图表提取 → 文本治理 → 模型候选与独立审核 → v7 证据发布 → 文本 CPT 数据增量。
当前实现生成预训练数据文件,不启动 GPU 训练。已有 v5/v6 发布与预训练命令继续保留;v7 使用本页的飞轮入口,避免绕过 tokenizer、来源准入和候选审核。
1. 环境和模型配置
建议在项目独立虚拟环境运行:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e '.[dev]'
激活环境后,以下命令使用该环境的 python。启动脚本依次选择显式 PYTHON_BIN、.venv/bin/python、兼容的 .venv-flywheel/bin/python、系统 python3。
将实际模型连接填写到项目 .env。已经有 .env 时只补字段,不用示例覆盖现有凭据。
| 角色 | 必需配置 | 何时启用 |
|---|---|---|
| 视觉描述 | FIN_DOC_VISION_API_URL/API_KEY/MODEL | methods 包含 visual |
| 独立评审 | FIN_DOC_PRETRAIN_REVIEW_API_URL/API_KEY/MODEL | 正式飞轮必需;视觉候选评审模型也需支持图像 |
| 翻译 | FIN_DOC_PRETRAIN_TRANSLATE_API_URL/API_KEY/MODEL | methods 包含 translate |
| 改写 | FIN_DOC_PRETRAIN_REWRITE_API_URL/API_KEY/MODEL | methods 包含 rewrite |
| 文本元数据治理 | 现有 LLM_API_URL/API_KEY/MODEL | governance_backend=auto 有 key 时启用;none 禁用 |
各角色支持 _MODEL_VERSION、_TIMEOUT、_MAX_TOKENS。供应商升级同名模型时,应修改版本字段,使旧结果保留并生成新版本。endpoint 填 OpenAI 兼容的 base URL,不填带凭据或 query 参数的地址。API key 只从环境读取,不保存到处理记录。
同时配置:
FIN_DOC_FLYWHEEL_OCR_BACKEND=local
FIN_DOC_PRETRAIN_TOKENIZER=/absolute/path/to/target-model/tokenizer.json
FIN_DOC_PRETRAIN_MAX_TOKENS=2048
FIN_DOC_FLYWHEEL_MAX_TASKS=100
FIN_DOC_FLYWHEEL_MAX_MODEL_REQUESTS=50
FIN_DOC_FLYWHEEL_MAX_SECONDS=7200
本地 OCR 使用现有 PADDLEOCR_LOCAL_API_URL;云端使用现有 cloud 配置。config/flywheel.json 默认关闭页级方向矫正和去畸变,保留原页面坐标,以便从 PDF 裁出表格图像,表格识别仍然开启。FIN_DOC_FLYWHEEL_OCR_OPTIONS 可以覆盖这组请求选项。旧 OCR 按保存的实际参数处理,参数未知或坐标变换不可核实时保留待复核记录,不推测裁剪区域。
OCR 返回的区域图片优先使用。outputImages 属于页面或可视化用途,不能直接当正文图表。PaddleOCR 官方结果字段说明是字段区分的依据。
预检:
python -m workflow.flywheel_cli preflight
预检检查依赖、启用模型的配置、OCR 连接配置和 tokenizer 文件,不请求网络服务。第一次实际调用仍可能出现供应商鉴权、上下文长度、图像支持或响应格式错误,这些会进入任务台账。
2. 来源和准入策略
来源目标继续放在 config/collection.json。生成配方、质量策略和预算放在 config/flywheel.json。学术发现默认分别扫描今日近期更新窗口、一个未完成的旧近期窗口和历史窗口,独立保存每个窗口的参数与 cursor;历史积压不阻断每日新增记录发现。近期窗口重叠两天并用稳定 ID 去重。返回结果集会随来源更新变化,首次真实试跑仍需抽查来源覆盖;Crossref 分页更新说明说明了这一限制。默认方法是 original 和 visual;要增加翻译、改写,可设置:
"methods": ["original", "visual", "translate", "rewrite"]
分页请求保持每个窗口的 query、过滤器和页大小不变,完整登记每页记录后才保存下一 cursor。发现预算按完整页计算,max_results 非页大小整数倍时可能多返回不足一页的记录,后续处理仍受任务预算限制。OpenAlex 页大小上限为 100;如需增加 API 配额,可在 .env 配置 OPENALEX_API_KEY,通过 Authorization header 发送,不拼入持久化 URL。参见 OpenAlex 官方鉴权说明。
source_policy 按来源名配置训练准入,设置 training=approved 后启用该来源的候选处理:
"source_policy": {
"cninfo": {"training": "approved", "usage_scope": "internal-only"}
}
source_policy 以来源名为粒度,training 和 allowed_methods 分别控制训练准入和候选生成方法。
默认 require_ocr_pass=true,OCR 有告警的候选先留待复核。原文、视觉描述、翻译、改写分别判定,技术失败进入有上限的重试;拒绝、截断、冲突和业务待复核不会自动反复请求。
建议首次少量运行并按四类候选抽查。视觉审核使用实际图片和显式记录的 OCR 上下文;数字差异是异常提示,由审核模型判断是否有来源支持,不作为唯一准入依据。
3. 日常操作
# 前台完整运行,便于首次观察
python -m workflow.flywheel_cli run
# 不发现新来源,补齐本地积压并回填已有 OCR
python -m workflow.flywheel_cli run --no-discover
# 状态与抽样
python -m workflow.flywheel_cli status
python -m workflow.flywheel_cli status --watch
python -m workflow.flywheel_cli report --latest --format markdown
python -m workflow.flywheel_cli audit --status needs_review --limit 20
python -m workflow.flywheel_cli audit --method visual --limit 10
# 显式人工判定,保留判定人、原因、输入 hash 和之前的决定
python -m workflow.flywheel_cli review-candidate \
--candidate-id CANDIDATE_ID --decision accepted --reviewer REVIEWER --reason '已核对原图和来源'
# 修复配置/服务后显式重试,保留旧尝试,新任务有新的身份
python -m workflow.flywheel_cli retry --task-id TASK_ID
# 回查完整多父级血缘
python -m workflow.flywheel_cli trace --sample-id SAMPLE_ID
python -m workflow.flywheel_cli trace --candidate-id CANDIDATE_ID
人工接受仍要求相应来源已批准训练使用。图片定位失败的记录保留原始 OCR、页码、bbox 和原因;应校正服务返回/坐标配置后重新处理该文档,不能用人工接受文字候选替代图像定位。
任务状态为 pending/running/succeeded/retry_wait/failed/deferred/rejected/needs_review;显式人工替换的旧任务为 superseded。租约和系统文件锁防止重复执行;持有每日整轮锁的新进程可以恢复已中断的旧任务。单项失败允许独立候选继续推进。
退出码:0 成功或无变化,1 部分完成/有积压,2 配置或整轮失败。每日摘要包含阶段错误、处理位置、修复建议、队列、视觉状态、候选状态、模型请求/用量、耗时、release 和数据集路径。errors 表示实际失败,stop_reasons 单独记录模型请求、任务或时间额度耗尽;额度停止后可续跑。错误摘要不输出供应商原始异常文本、请求体或凭证。请求预算跨治理、视觉、翻译、改写、评审共享;用量未返回时记录缺失。
report --latest --format markdown 只显示所选日期的最新运行和可读诊断;不加 --latest 汇总当天全部运行,默认 JSON 也包含顶层 errors 和 stop_reasons。旧版本下载错误只记了类型时,报告会尝试从当前下载清单补充原因,并标记 details_from=current_download_manifest。
运行中查看进度
使用本地试跑配置时,在另一个终端运行:
python -m workflow.flywheel_cli --config config/flywheel.local.json --data-root data status --watch
每 5 秒刷新一次,显示当前外层运行、文档、阶段、耗时、最近活动和范围内各阶段任务数。--interval 10 可调整刷新间隔;Ctrl-C 只退出查看,数据处理继续。检测到本轮结束或进程已退出时,查看命令自动结束。任务会动态增加,因此不显示整条流水线的完成百分比或预计结束时间。
新启动的 run 会向 stderr 输出阶段进度,并在 manifests/progress/<run_id>.json 原子保存进度快照。治理阶段细分为表格摘要、文档元数据、文本块上下文,显示已完成/总数,以及本轮模型请求、响应、失败和缓存命中数;等待模型时显示对应角色。run --no-progress 关闭终端进度输出,最终 JSON 仍输出到 stdout。进度文件不包含提示词、模型响应或凭证。
status --format text 单次显示可读状态,默认单次 status 返回 JSON 和 progress 字段。缺少细分进度的旧记录会显示任务阶段、最近完成步骤和成功落盘响应数。status 只读本地数据库与文件。
已有数据根目录默认会回填所有本地 OCR,并领取所有来源的积压任务。小范围试跑时,可在本地 flywheel JSON 设置 "processing_scope": "collection":回填与任务领取仅处理采集配置中启用的来源和财报公司/年度/类型;关闭 scholarly 后不会继续处理其旧论文队列。status.active_queue 为范围内快照,queue 仍保留全库快照;已有任务和文件不会删除。该选项控制任务执行,语料发布和资产统计仍沿用现有全库规则。默认 "all" 保持原行为;范围调整不改变处理配方身份,已有成功任务可继续复用。
任务数和整轮时限在任务切换时检查,正在执行的 HTTP/OCR 请求使用各自的 timeout。模型响应逐次原子保存,续跑时复用已落盘的成功响应。
4. 本地数据和数据库
所有输出在统一 data_root 下;默认 data,可用 FIN_DOC_DATA_ROOT 或 CLI 全局 --data-root 调整。飞轮状态数据库固定为该根目录的 state/pipeline.db,不继承指向其他数据根目录的旧 FIN_DOC_STATE_DB。
| 路径/表 | 内容 |
|---|---|
processing_task | 持久任务、依赖、重试、租约、执行结果 |
visual_asset | 图和表共用表,保留类型、来源、页码、bbox、图像 hash/路径与元数据 |
visual_description | 每个图表的模型描述版本 |
artifact_edge | 多输入依赖图;拒绝形成环 |
training_candidate | 候选方法、内容身份、准入状态与判定 |
training_sample/training_origin | 跨日内容去重、全部来源与实际 split |
media/blobs | 按图片字节 hash 共用文件;不同出现位置各自保留记录 |
media/tables | 表格原 OCR HTML/内容和治理 Markdown 表示 |
media/contexts | 实际关联的 OCR 上下文证据 |
media/unresolved | 无法安全定位的图表记录 |
processed/governed_versions | 按 OCR/规则/模型身份保存正文治理版本 |
processed/visual_descriptions、processed/transforms | 原始模型响应、实际提示词、输入身份 |
training/candidates、training/decisions | 候选与模型/人工质量判定文件 |
manifests/daily | 每日摘要 |
manifests/progress | 外层运行的实时阶段、细分计数和模型请求计数 |
首次在已有数据库增加飞轮表前,通过 SQLite backup API 保存 pipeline.db.before-flywheel.bak。迁移为增量建表,不删除旧表,由需要写入数据库的操作触发;status 和 preflight 不迁移数据库。回填已有 OCR 不再次调用 OCR 服务。
恢复数据库前先停调度,并同时保存数据库、WAL 和整个数据根目录的当前副本;不要只移动正在使用的 .db 文件。旧备份恢复后,新增队列和人工判定可能需要从新备份恢复,不能假设仅靠语料文件重建全部状态。
5. 发布与训练数据
治理包位于 published/flywheel/RELEASE_ID。v7 包含正文记录、图表清单、描述、候选、决定、artifact DAG 与证据文件。artifacts.jsonl 将来源路径映射到包内 evidence 路径,checksums.sha256 提供文件完整性校验。
正式语料只从校验通过的 v7 冻结候选读取。每日训练增量位于 training/pretrain/DELTA_ID,包括 corpus.jsonl、provenance.jsonl、excluded.jsonl、manifest.json 和 checksums.sha256。token 上限按目标 tokenizer 对最终正文计数,不包括训练程序未来自行添加的 special tokens;训练程序需自行预留相应空间。样本格式包括 sample_id/text/split/token_count。
没有新样本时不生成空训练数据集。若只有新血缘,则在 training/origin_deltas 保存血缘增量。完全没有变化则记录 no_change。发布目录原子落盘后 SQLite 索引尚未提交时,下一轮验证文件并恢复索引。
同一逻辑作品的原文、翻译、改写和视觉描述共用划分。重复内容连接的作品也沿用同一组;新增连接若同时碰到已经发布的 train 和 validation,相关候选先隔离为 split conflict,保持已发布数据不变,等待重新选择/构建划分。去重和分组按 tokenizer、token 上限、划分比例及脱敏版本形成的 recipe 隔离;切换目标 tokenizer 不会被旧语料索引误判为已经导出。当前内容版本策略是追加不同的合格内容,不自动删除旧模型版本。
累计快照显式选择增量:
python -m workflow.flywheel_cli snapshot \
--dataset-id finance-cpt-v1 --delta DELTA_1 --delta DELTA_2 \
--origin-delta OPTIONAL_LINEAGE_DELTA
python -m workflow.flywheel_cli verify data/training/snapshots/finance-cpt-v1
选定增量若引用更早样本,需包含其原始增量。不同 tokenizer 配方不能混合。近似重复报告采用有界字符 n-gram Jaccard,仅报告,不自动删除;报告记录采样长度、比较上限和是否检查完整。
6. 每日定时
scripts/run_collection.sh 已转为飞轮的兼容启动入口;scripts/run_flywheel.sh 安全加载 Python 环境并把输出追加到 logs/flywheel.log。旧的独立采集 CLI 仍可手动使用,但不要同时给旧流程和飞轮安装定时任务。
使用 cron 或 launchd 模板配置每日运行:
Linux/macOS cron 示例是 ops/fin-doc-flywheel.cron.example,默认主机当地时间每天 03:00。模板路径需改为实际仓库绝对路径;核对主机系统时区,例如 Asia/Shanghai。日志目录由脚本创建。
macOS launchd 模板是 ops/com.chansn.fin-doc-flywheel.plist.example,每天 03:00,登录加载时也运行一次,便于补齐积压。先修改模板中的仓库路径,再启用:
mkdir -p "$HOME/Library/LaunchAgents"
cp ops/com.chansn.fin-doc-flywheel.plist.example "$HOME/Library/LaunchAgents/com.chansn.fin-doc-flywheel.plist"
launchctl bootstrap "gui/$(id -u)" "$HOME/Library/LaunchAgents/com.chansn.fin-doc-flywheel.plist"
停用:
launchctl bootout "gui/$(id -u)" "$HOME/Library/LaunchAgents/com.chansn.fin-doc-flywheel.plist"
日历触发使用 macOS 系统时区。停机或 OCR 服务不可达期间的任务保留在队列,恢复后继续处理。
7. 可选 SFT 阶段
在本机飞轮配方中设置 "sft": {"enabled": true, "config": "config/sft.local.json"}, 即可在发布与 CPT 构建后生成问答、JSON 抽取和表格计算 SFT;默认为关闭。 需要额外配置生成与审核角色,表格审核需要视觉模型。 每日摘要的 sft_dataset 记录结果;SFT 请求数加入总数,详细用量位于该字段内。 独立生成、输出格式及续作方式见 SFT 数据生成。