ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

axolotl 多模态 Assistant-only Loss Masking 完整指南:`role_boundaries` 配置、运行时验证与源码级原理

axolotl 多模态 Assistant-only Loss Masking 完整指南:`role_boundaries` 配置、运行时验证与源码级原理 axolotl 多模态 Assistant-only Loss Masking 完整指南role_boundaries配置、运行时验证与源码级原理【免费下载链接】axolotlGo ahead and axolotl questions项目地址: https://gitcode.com/GitHub_Trending/ax/axolotl多模态模型微调中系统提示、用户问题与图片占位 token 不应参与 loss 计算否则模型会背答案而不是学习回答。本文以 axolotl 的docs/multimodal_assistant_mask.md为核心完整讲解仅对 assistant 回复计算 loss 的配置落点train_on_inputs/roles_to_train/train_on_eos的层级关系、运行时如何通过日志自检以及用cfg.role_boundaries为内置策略或自定义 chat template 声明角色边界标记的完整格式与语义。读完你将能正确配置多模态 assistant-only masking并通过 processing_strategies.py 与 causal.py 的源码理解其底层扫描、掩码与校验逻辑。一、正确的位置三个关键配置项的层级关系多模态MM模型的 loss masking 由三个配置项协同控制它们必须放在正确的层级这是最常见的配置错误来源配置项层级作用train_on_inputs顶层Top-level全局开关true时所有 token 都参与 loss不做角色屏蔽roles_to_train每个 dataset 下per-dataset声明哪些角色参与 loss默认 assistanttrain_on_eos每个 dataset 下per-dataset控制每个 turn 的结束标记是否参与 loss正确的配置结构如下原始文档中的规范示例# Top-level: only train_on_inputs lives here. train_on_inputs: false datasets: - path: data/train.jsonl type: chat_template roles_to_train: # per-dataset — this is what the MM scanner reads - assistant train_on_eos: turn # per-dataset — same test_datasets: - path: data/val.jsonl type: chat_template split: train roles_to_train: - assistant train_on_eos: turn关键点train_on_inputs: false是总开关。为true时多模态扫描器直接跳过角色屏蔽见源码中_mask_non_assistant_keep的短路分支if self.train_on_inputs: return torch.ones_like(...)processing_strategies.py。roles_to_train与train_on_eos必须放在datasets[0]/test_datasets[0]之下而不是顶层。多模态 collator 在 causal.py 中通过_ds_get(ds_cfg, roles_to_train)从每个 dataset 配置读取这两个值。如果它们被误放在根级扫描器读取到的就是None角色屏蔽不会生效。train_on_eos支持turn仅可训练 turn 的结束标记参与 loss、all始终参与、none从不参与、last仅序列中最后一个可训练 turn 的结束标记参与四种取值与纯文本ChatTemplateStrategy保持一致processing_strategies.py。二、如何在运行时验证配置是否生效2.1 查看 collator 的 INFO 日志build_collator会在非 eval 构建时把最终解析到的配置项以 INFO 级别打印出来causal.pyMM collator: train_on_inputsFalse roles_to_train[assistant] train_on_eosturn role_boundaries_overridenone自检规则如果roles_to_train打印为None说明 YAML 中的配置项没有到达扫描器——请检查它们是否放在datasets[0]下而不是根级。如果role_boundaries_overridenone说明你没有使用cfg.role_boundaries走的是策略内置标记如果该策略声明了内置标记的话。2.2 查看 ProcessingStrategy 初始化日志每个验证过的策略在初始化时还会打印解析后的边界 token idprocessing_strategies.pyProcessingStrategy init: classGemma4ProcessingStrategy train_on_inputsFalse roles_to_train[assistant] train_on_eosturn boundaries_sourcebuilt-in boundaries2 built-in例如文档中提到的 Gemma 4 示例|turnmodel→[105, 4368]turn|→[106]。这些 id 由tokenizer.encode(..., add_special_tokensFalse)在策略初始化时解析得出。2.3 识别 fallback 路径如果某个策略在初始化时打印了一次性警告has no built-in role boundaries ... only pad and media tokens are masked说明该策略没有声明内置角色边界正处于fallback 路径系统提示、用户和 assistant 的所有 token 都会参与 loss只有 pad 与图片 token 被屏蔽processing_strategies.py。此时必须通过cfg.role_boundaries下文第三节显式声明每角色的标记来激活角色屏蔽。从源码结构看当前仓库 processing_strategies.py 中已内置角色边界_build_role_boundaries返回非空的策略包括Qwen2VLProcessingStrategyChatML|im_start|风格L755、Gemma3ProcessingStrategy/Gemma3nProcessingStrategy_GemmaTurnStrategyL878/L932、Gemma4ProcessingStrategyL958、Llama3_2VisionProcessingStrategyL1042、Llama4ProcessingStrategyL1063、MistralV7TekkenProcessingStrategyL1117、VoxtralProcessingStrategyL1158、Mistral3ProcessingStrategyL1248、SmolVLM2ProcessingStrategyL1211等而PixtralProcessingStrategyL1082依赖end: eos_token语义、InternVLProcessingStrategyL1330与Glm4vProcessingStrategyL1383则属于unverified / fallback warn路径L1162、L1333、L1387 的注释与警告即为证据需要用户通过cfg.role_boundaries激活屏蔽。三、配置式覆盖cfg.role_boundaries对于上述未验证的策略或使用了无法匹配内置策略标记的自定义 chat template可以直接在 YAML 中声明角色边界无需继承或编写子类role_boundaries: - role: assistant start: |turnmodel end: turn| - role: user start: |turnuser end: turn| # Optional keys: # include_start: false # default False # include_end: true # default True, respects cfg.train_on_eos # end: eos_token # sentinel: resolves to tokenizer.eos_token_id # end: null # span runs to end of sequence该字段由 multimodal.py 中的RoleBoundarySpecschema 定义并通过cfg.role_boundaries传入 collator最终在 causal.py 中转换为role_boundaries_override交给处理策略。3.1 语义与规则字面字符串编码start和end都是字面字符串axolotl 在策略初始化时通过tokenizer.encode(..., add_special_tokensFalse)将其编码为 token id 序列并在 INFO 级别日志中打印解析结果_encode_markers与_resolve_role_boundary_overrideprocessing_strategies.py。end: eos_token哨兵值这是表达 Pixtral 风格的 assistant turn 以 EOS 结尾 的可移植写法不必硬编码 tokenizer 的 id源码中解析为tokenizer.eos_token_idL725-L732。若 tokenizer 没有eos_token_id会直接报错。end: null省略表示该角色的 span 一直延伸到序列末尾RoleBoundary.end_tokens为空列表见 processing_strategies.py。opt-in 覆盖整体替换role_boundaries是选择加入的覆盖项。非空列表会整体替换策略内置声明部分叠加故意不支持——review 时难以推理。字段未设置或设为空列表[]都表示使用策略内置标记。写role_boundaries: []几乎总是拼写错误或遗留代码——如果按字面执行会产生全屏蔽的 labels 和零梯度因此它与未设置同等对待源码中的 truthiness 检查L98-L116。roles_to_train仍决定哪些角色贡献 loss可以同时声明user和assistant的边界并将roles_to_train: [assistant]这样扫描器能正确识别 user span 作为屏蔽边界而不会在 user 内容上训练bnd_role_in_loss [b.role in roles_to_train ...]L598。失败时快速报错非法配置在策略初始化阶段就会报错而不是在 loss 计算时静默失败——包括缺少role/start字段L710-L714、start/end 标记编码为空序列L716-L720、L735-L741、以及 tokenizer 无eos_token_id却使用end: eos_tokenL727-L731。3.2 可选键的默认值键默认值说明include_startfalse起始标记本身是否计入 loss默认不计include_endtrue结束标记本身是否计入 loss默认计入受train_on_eos约束四、源码级原理扫描器如何工作4.1 掩码扫描的两条路径_mask_non_assistant_keep会根据 torch 线程数选择扫描器processing_strategies.py单线程torch.get_num_threads() 1时走向量化路径_compute_role_keep_mask_vectorizedL510输出与参考实现逐字节一致多线程时走参考实现_compute_role_keep_maskL393因为向量化路径在多线程 torch 下会退化 9-13 倍源码注释 L362 明确记录了这一权衡。4.2 扫描与掩码语义贪心左扫描 最长前缀优先在 token 序列上从左向右扫描当多个角色的 start 标记在同一位置都能匹配时取 start token 序列最长的那个用于消歧嵌套标记例如|im_start|assistant与|im_start|见_apply_role_boundaries的 docstringL489-L507。屏蔽范围对每个匹配到的可训练角色 span把start_of_content到内容结束之间的 token 置为保留mask[i][start_of_content:content_end] 1L454include_start/include_end决定起始与结束标记本身是否保留不可训练角色的 span 不保留。train_on_eos的四种模式turn只在可训练 turn 保留结束标记L457-L462last先记录每个可训练 turn 的结束 span扫描结束后只保留最后一个L463-L464、L482-L484none从不保留all对不可训练角色也按include_end门控保留结束标记——这是为了让 Pixtral / Mistral V7 Tekken 共享的[/INST]不泄漏L466-L470。include_endFalse回退匹配当结束标记不作为 loss 且非空时扫描器会回退一步让该结束标记可被下一次迭代重新匹配为下一个边界的起始标记——适用于 Pixtral / Mistral V7 Tekken 中 user 结束与 assistant 起始共享同一[/INST]的场景L472-L480、L654-L658。边界缺失回退没有任何角色边界时仅屏蔽 pad 与 image tokenprocess_labels中keep (input_ids ! pad_id)与keep (input_ids ! image_token_id)L381-L390其余 token 全部保留。4.3 最终标签生成process_labels将 keep mask 与 pad、image token 的排除条件合并后把不保留的位置置为-100交叉熵忽略值_apply_role_boundaries同理L489-L507从而保证 loss 只来自 assistant 回复内容。五、配置核对清单train_on_inputs放在顶层roles_to_train/train_on_eos放在每个 dataset 下训练启动后检查日志中的MM collator: ...行确认roles_to_train不是None若走 fallback 路径看到一次性警告在 YAML 顶层配置cfg.role_boundaries声明每个角色的start/end标记需要只训练 assistant 时同时声明 user 边界并保持roles_to_train: [assistant]让扫描器正确识别屏蔽边界检查策略初始化日志中解析出的边界 token id 是否符合预期例如 Gemma 4 的|turnmodel→[105, 4368]配置非法时错误会在策略初始化阶段立即抛出此时根据报错信息修正标记字符串即可。通过以上步骤你可以在 axolotl 中对任意多模态模型包括未内置验证的策略可靠地实现 assistant-only loss masking并在训练日志中随时确认其实际生效状态。【免费下载链接】axolotlGo ahead and axolotl questions项目地址: https://gitcode.com/GitHub_Trending/ax/axolotl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表