Daily training releases, recovery and reports
The optional daily path is collection → OCR/governance → CPT/SFT → cumulative snapshot → near deduplication → mixture → coverage report → release. Keep provider credentials and operating options in the project-root .env. Final publication and SFT are disabled by default.
One environment file
Add fields to your existing .env; do not overwrite it. Process environment variables take precedence. Restart persistent channel processes after edits. Python parses this file as data; do not source JSON configuration through a shell.
FIN_DOC_RELEASE_ENABLED=true
FIN_DOC_RELEASE_NEAR_DEDUP=true
FIN_DOC_REPORT_TIMEZONE=Asia/Shanghai
FIN_DOC_SFT_ENABLED=false
FIN_DOC_FLYWHEEL_POLICY={"methods":["original","visual"],"source_policy":{"your-source":{"training":"approved","usage_scope":"internal-only"}}}
FIN_DOC_RELEASE_CPT_MIXTURE={"method":"temperature","alpha":1.0,"group_fields":["source_name"],"unit":"tokens","budget":null,"seed":42,"max_per_family":null,"redistribute":true,"allow_shortfall":false}
FIN_DOC_RELEASE_SFT_MIXTURE={"method":"temperature","alpha":1.0,"group_fields":["task"],"unit":"samples","budget":null,"seed":42,"max_per_family":null,"redistribute":true,"allow_shortfall":false}
FIN_DOC_RELEASE_NEAR_OPTIONS={"threshold":0.9,"ngram":5,"num_perm":64,"bands":16,"min_chars":80,"max_candidates":10000,"max_chars":200000}
FIN_DOC_RELEASE_COVERAGE_TARGETS=[{"field":"method","label":"original","min_samples":100}]
Replace your-source with a source approved for your intended training use. Configure the existing model and tokenizer variables from .env.example. JSON must fit on one line. FIN_DOC_FLYWHEEL_POLICY overrides top-level fields of the shipped recipe: nested objects such as source_policy are replaced completely. Include all sources you intend to retain. Existing dedicated environment variables take precedence over these overrides. Templates remain versioned defaults; daily operation does not require editing several JSON files.
For SFT, configure the required roles and add:
FIN_DOC_SFT_ENABLED=true
FIN_DOC_SFT_CONFIG=config/sft.json
FIN_DOC_SFT_POLICY={"tasks":["document_qa","extraction","visual_qa"],"strategies":["direct"],"max_jobs":20,"max_model_requests":40}
The recipe path is optional. visual_qa requires vision generation and review models. FIN_DOC_SFT_POLICY applies to both standalone and daily SFT. Publication option changes do not invalidate upstream generation caches.
Mixtures
Daily publication supports fixed and temperature. Fixed weights keys must match the actual pool groups. CPT uses training-tokenizer tokens or samples; SFT uses samples. Validation remains complete and is neither approximately deduplicated nor mixed. budget:null targets all eligible training units; defaults use alpha:1, no family cap and redistribution. Whole-sample granularity, quotas or family caps may produce a shortfall. By default the candidate mixture and diagnostic remain available but latest does not advance. allow_shortfall:true explicitly permits a nonempty shortfall release; the deficit remains visible. DoReMi/RegMix remain explicit experiments on frozen pools, without daily proxy training or reuse of mismatched historical weights.
Run and resume
python -m workflow.flywheel_cli preflight
python -m workflow.flywheel_cli run
python -m workflow.flywheel_cli publish-training
python -m workflow.flywheel_cli publish-training --sft-dataset data/training/sft/datasets/sft-example
python -m workflow.flywheel_cli status
python -m workflow.flywheel_cli report --date 2026-10-04
publish-training resumes publication only, without collection, OCR or model calls. It still needs the same data root, source policy, tokenizer file and local dependencies; SFT recipe identities include model configuration. An explicit SFT snapshot must be complete, match the recipe and remain approved. Existing schedulers can keep calling scripts/run_flywheel.sh. No scheduler is installed automatically.
Durable records and lineage
The existing state/pipeline.db stores:
| Record kind | Purpose |
|---|---|
training-input | Verified package identities and candidate/sample parents |
training-stage | Stage inputs, attempts, status, output hash and artifact |
training-index | Persistent near-dedup index registration |
training-export-sample | Exported sample IDs mapped to original lineage |
training-release / training-latest | Immutable versions and the database projection of latest |
daily-start / daily | Starting inventory, interruption recovery and run reports |
Stage keys bind input inventories and recipes. Completed outputs are verified before reuse. If a directory rename completed before the database write, recovery registers the artifact and its parents. Missing or changed registered outputs stop publication. Back up the database and files together. CPT combines all deltas and lineage deltas for the current tokenizer/chunking recipe. SFT uses a cumulative snapshot for the selected evidence release; daily SFT snapshots are not concatenated. Completed SFT exports with identical evidence, recipe and source policy are reused. Partial generation resumes through existing job/response caches in another immutable export.
Near-dedup indexes are separated by kind, recipe and settings and retain historical fingerprints. Historical matches outside the current pool remain report-only; removal requires a directly similar retained representative in the current pool. See near deduplication. Upstream evidence identity excludes downstream SFT, reports and publication artifacts, avoiding recursive version churn. Time limits are checked between stages; an in-progress verification, copy or MinHash calculation may exceed the soft deadline.
Immutable versions
data/
training/pretrain/ # Original daily CPT deltas
training/origin_deltas/
training/snapshots/daily-<hash>/
training/mixtures/cpt-<hash>/ # May have a quota shortfall
training/releases/release-<hash>/
manifest.json
checksums.sha256
cpt/
sft/ # If enabled, includes original images
reports/cpt/
reports/sft/
training/latest.json
indexes/daily-<kind>-<recipe>.sqlite
reports/daily/YYYY-MM-DD.json
reports/daily/YYYY-MM-DD.md
python -m workflow.flywheel_cli verify-training data/training/releases/release-ACTUAL_HASH
python -m workflow.flywheel_cli trace --sample-id EXPORTED_SAMPLE_ID
Each version contains independently verifiable mixture packages and reports. Training files/images are portable; full historical tracing needs the original database and source artifacts. Recorded source paths are audit metadata, not required loading paths on another machine. Identical inputs/options reuse a version. Historical versions are neither overwritten nor deleted.
latest.json advances by atomic replacement only after the complete version and nested packages/reports verify. Incomplete SFT, empty selections, disallowed shortfalls or integrity failures preserve the previous version. The file pointer is the publication commit point; the next execution repairs its database projection if a process exited between the pointer replacement and database update. Withdrawn source/candidate approval blocks publication of historical CPT inputs until a reviewed corpus is rebuilt; old versions are not retroactively deleted. When SFT is enabled both tracks publish together, while original daily CPT deltas remain independently available.
Complete reports
Per-run JSON lives at manifests/daily/<run_id>.json; calendar-day JSON/Markdown uses FIN_DOC_REPORT_TIMEZONE under reports/daily/. The CLI, channel report commands and MCP share aggregation semantics:
- Task status, errors, queue backlog, candidate review and image/table inventories; model requests and raw usage without cost estimates.
- Newly registered candidates, visual assets, CPT samples/origins and SFT samples. Recovery registrations count as additions.
- Stage built/reused/indexed results, timing, paths and failure reasons.
- Current version, input/removed/selected samples, train/validation sizes, target/actual quotas, groups and shortfalls.
- Version reports include coverage targets and changes against the previous version. Tokenizer changes disable incompatible token comparisons.
Multiple runs on one day sum task/request/addition counters, while queue and dataset inventories remain latest snapshots. Caught failures attempt to persist a report. Abrupt termination is recorded as interrupted on the next locked run; unpersisted request/task counts are unavailable.