图表多模态 SFT
从已批准的图表候选和原始区域图片生成真正包含图片的训练样本。 原有文本 SFT保持可用,多模态任务使用独立配方与模型角色。
| 任务 | 输入 | 输出 |
|---|---|---|
visual_qa | 图片或表格原图+问题 | 由图中可见内容支持的答案 |
table_structure | 完整、清晰的简单矩形表格图片+固定抽取指令 | 含 title、unit、columns、rows 的 JSON |
生成和独立审核均附原图。训练消息不包含 OCR 文本或已生成的描述, 审核也不读取邻近 OCR 上下文,要求仅凭提供给训练模型的图片就能回答。 OCR 仅作为生成时的辅助提示,不能补充图片之外的信息。
配置与生成
复制多模态配方:
cp -n config/sft-vision.json config/sft-vision.local.json
在本机 .env 中填写下面两组配置;两个模型都必须支持图片输入:
FIN_DOC_SFT_VISION_GENERATE_API_URL=https://your-provider.example/v1
FIN_DOC_SFT_VISION_GENERATE_API_KEY=YOUR_LOCAL_KEY
FIN_DOC_SFT_VISION_GENERATE_MODEL=YOUR_VISION_GENERATOR
FIN_DOC_SFT_VISION_REVIEW_API_URL=https://your-provider.example/v1
FIN_DOC_SFT_VISION_REVIEW_API_KEY=YOUR_LOCAL_KEY
FIN_DOC_SFT_VISION_REVIEW_MODEL=YOUR_VISION_REVIEWER
只启用多模态任务时,配置 FIN_DOC_SFT_VISION_GENERATE_* 和 FIN_DOC_SFT_VISION_REVIEW_*。在同一配方中加入文本任务时,同时配置文本生成与审核角色。
python -m training.sft_cli --config config/sft-vision.local.json preflight
python -m training.sft_cli \
--config config/sft-vision.local.json \
--flywheel-config config/flywheel.local.json \
--data-root data \
build --dataset-id vision-sft-001 --release YOUR_V7_RELEASE_ID
输入仍需本机 v7 发布包与对应数据库;当前来源准入和上游候选审核必须通过。 飞轮需要先启用 visual 方法并完成图表审核,才能得到可用的视觉候选。 达到次数/时间限制后,使用新 dataset ID、相同配方和发布包续作。
每日自动运行只需把本机飞轮配置指向多模态配方:
"sft": {"enabled": true, "config": "config/sft-vision.local.json"}
默认飞轮仍关闭 SFT。一个每日运行使用一个 SFT 配方,配方的 tasks 可以同时包含五种文本/多模态任务。
质量约束
- 每个视觉样本需附有证据区域,坐标为相对于当前裁剪图的 0–1000 整数;区域及观察记录用于审核,不放入训练输入。
- 审核必须确认事实、数值、单位、日期、图片内可回答性、区域定位;表格转 JSON 还必须确认完整抄录。
- 表格只处理简单矩形结构;合并单元格、复杂多层表头、图片被截断或文字不可辨认时应跳过或待复核。
- 单元格保留字符串,不擅自转换数值、填充或换算单位;只有可见空白单元格使用 null,不能用 null 代替无法辨认的内容。
- 配方默认最多 50 行、20 列、500 个数据单元格;超限拒绝,不截掉行列。
- 图片默认最多 10 MiB、4000 万像素,须是单帧 PNG,并校验原图哈希。不会自动降采样或修改原图。
对应参数:max_table_rows、max_table_columns、max_table_cells、max_image_bytes、max_image_pixels。 问题/答案字符上限与其他 SFT 任务相同。若大表无法在模型输出限制内完整返回,应排除或调整配方,而非拼接截断结果。 区域位置、数值与图像事实由独立视觉审核模型检查。 图片按原字节打包。
便携导出与加载
SFT v2 输出分别存放文本与多模态数据:
| 文件 | 内容 |
|---|---|
train.jsonl、validation.jsonl | 纯文本训练样本;仅视觉配方时为空 |
train.vision.jsonl、validation.vision.jsonl | 含图片引用和类型化消息的多模态样本 |
images/<sha256>.png | 随数据集复制的原图,相同图像只存一份 |
images.jsonl | 哈希、尺寸、文件大小及原图工件血缘 |
samples.jsonl | 完整样本、任务、审核与证据区域 |
其余 evidence、audit、jobs、manifest 和 checksums 文件延续文本 SFT。 manifest.json 增加模态数量、图片数量与导出文件索引。 把整个数据集目录移动到另一台机器后,训练图片引用仍然有效;完整历史审计仍需原数据目录。
样本结构示例:
{
"sample_id": "sft-example",
"images": ["images/IMAGE_SHA256.png"],
"messages": [
{"role": "system", "content": [{"type": "text", "text": "仅依据图片回答。"}]},
{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": "图表显示的报告期是什么?"}]},
{"role": "assistant", "content": [{"type": "text", "text": "图片中标出的报告期。"}]}
]
}
images 在磁盘 JSONL 中是数据集目录内的相对路径。实际交给训练框架时需加载图片。 仓库提供按条读取的 PIL 适配器,不依赖 transformers、datasets 或 TRL:
from training.sft_export import load_vision_records
records = load_vision_records("data/training/sft/datasets/vision-sft-001", split="train")
for example in records:
# example 包含 messages 和 images;images 中是真实 PIL.Image 对象。
# 将 example 交给你选择的多模态训练程序。
print(len(example["images"]))
消息结构参考 TRL 视觉数据格式:类型化 content 与独立 images。在训练程序中配置目标模型的 processor、chat template、图像 token 和批处理方式。训练入口见单卡 SFT。
校验、划分和版本
python -m training.sft_cli verify data/training/sft/datasets/vision-sft-001
python -m workflow.flywheel_cli --data-root data trace --sample-id YOUR_SFT_SAMPLE_ID
verify 对 v2 除 checksum 外,还检查训练文件与完整样本的一致性、图片引用、尺寸与哈希、占位符数量、 图片是否跨训练/验证集。老的 v1 文本数据包仍能执行 checksum 校验。
划分继承逻辑文档和已有 CPT 约束,并增加相同图片字节的约束。不同来源、不同 OCR 上下文引用同一图像时, 仍归入同一划分;与历史划分冲突则排除。不同裁剪、缩放、重新编码的相似图片不属于字节级去重范围。 多模态样本身份包含图像哈希,避免把两张图上的相同问答误合并。
引擎更新为 sft-v2,会生成新的配方身份;继续生成时请使用新的 dataset ID。 旧数据和审计不改写;完全相同请求的模型响应仍可命中缓存。 新文本/多模态导出都是累计快照,不能直接拼接多次续作结果。
描述与多轮问答
config/sft-vision-methods.json 额外支持 visual_description 和 visual_conversation,见生成方法。多轮图片仅放在首个 user 消息,后续轮次共享该图;原图随包导出。