ARTICLE DETAIL

资讯详情

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

OPD teacher log-probs 对不上?Claude Code 的 Base URL 走 TaoToken 通道再查 combine_loss.py

OPD teacher log-probs 对不上?Claude Code 的 Base URL 走 TaoToken 通道再查 combine_loss.py 翻 OpenClaw-RL 的 OPD 分支时一个典型的卡点是这样出现的topk_distillation_loss.py里明明算出了distill_token_ids[pos][k]和distill_logprobs[pos][k]按A_t logπ_teacher − logπ_student也应该有逐 token 的方向性信号但流到combine_loss.py之后advantage 要么整段贴 0要么全回答同号看不出哪些 token 该上调、哪些该下调。本地终端里grep -rn advantage来回翻两三遍人眼还是很难把两份文件的数组形状和语义对齐——因为一个是 top-k 的二维结构一个是 per-token 的标量中间还夹着 reward0、teacher_log_probs 置等这两个解耦开关。这篇记录的排障路径是先到 TaoToken 官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopd_teacher_logprobs 创建一个 Key再把 Claude Code 的 Base URL 指向https://taotoken.net/api不要带/v1也不要填官网地址让模型直接读combine_loss.py和topk_distillation_loss.py按公式逐行核对两个分支的解耦条件。TaoToken 只负责模型通道的 Key 和 Base URL不介入 OPD 的公式与实现公式本身仍然要回到源码里去对。1. 先定位对不上的地方advantage 在哪个环节被改写OPD 的原始流程是可以一句话说清的student 先 rollout 出一整段 agent 对话含 tool calls 与 tool results从(assistant_turn, next_state)对里让 LLM judge 抽 hint把 hint 追加到原 prompt 末尾拼成 enhanced prompt再把 enhanced prompt 加上 student 原始回复的 token 一起送进 teacher 模型取回 student 每个 token 位置上的 top-k log-probs最后逐 token 算A_t logπ_teacher(a_t | shint) − logπ_student(a_t | s)。对不上的地方几乎全部集中在最后一步到combine_loss.py之间。核对时按顺序查这四件事第一teacher 那侧的 log-prob 是学生实际 token 的概率还是teacher 自己 top-k 里第 0 列的概率。distill_token_ids[pos][k]给出的是 top-k 候选 token如果取数时直接取 max 或取 k0那算出来的就是 teacher 的偏好分布而不是 teacher 对 student 所选 token 的评价逐 token 优势会整体偏正。第二position 轴对齐的是 enhanced prompt 的偏移还是 response 的相对偏移。hint 追加在 prompt 末尾会改变整个序列长度teacher 侧输出里 response token 的起始位置发生了平移。如果两边一个用绝对偏移、一个用 response 内相对偏移除了首 token后面全部错位表现就是信号看着有但方向随机。第三student 侧 log-prob 是否来自同一套 tokenizer 与同一段序列。rollout 时缓存的rollout_log_probs是在原始 prompt 上算的teacher 蒸馏阶段重新 tokenize 过 enhanced prompt若两段文本的 token 边界因拼接空白或特殊符号发生漂移对上的位置就为数不多了。第四loss_mask覆盖的区间是否只落在 response token 上。prompt 段和 tool result 段若被误置为 1这些位置的 teacher−student 差异会稀释掉真正的 response 信号advantage 的方差看起来变小、均值贴近 0容易误判成实现没生效。这四点里任何一点出错都会表现为combine_loss.py和topk_distillation_loss.py对不上公式。人工 grep 的劣势在于两边的数组形状不同、命名也不同肉眼很难稳定地把distill_logprobs[pos][k]与 loss 里用的逐 token 量映射起来。2. TaoToken 接入前置拿 Key 与确认模型 ID先把模型通道独立出来。打开https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopd_teacher_logprobs在控制台创建一个 Key得到形如YOUR_API_KEY的字符串。同时在模型广场确认这次排查要用的模型 ID——读代码、交叉核对两个 loss 文件属于长上下文推理选一个上下文足够、能稳定跟随逐行对照指令的模型即可。模型 ID 以官网模型广场当前展示的为准不要在配置里手写来源不明的字符串。这里需要划一条边界TaoToken 提供的是模型通道上的 Key 与 Base URLOPD 的 hint judge、teacher log-probs 计算、advantage 合并逻辑都属于项目自身的实现通道不会也不应该去改动它们。你在 Claude Code 里问的每一个问题最终答案的来源仍然是仓库里的那两个.py文件。3. Claude Code 侧的可复制配置Claude Code 读取的配置在~/.claude/settings.json也可以放项目级.claude/settings.json。把三项 environment 写进去{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_MODEL: 模型广场里的模型 ID } }三个值分别对应Base URL 只填到https://taotoken.net/api末尾不要带/v1也不要填官网首页那条带查询参数的地址ANTHROPIC_AUTH_TOKEN用第 2 步创建的 KeyANTHROPIC_MODEL用模型广场确认过的 ID。SDK 会在 Base URL 之后自行拼接/v1/messages所以路径不要提前写死。如果你习惯用 shell 环境变量而不是 settings.json等价写法是export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_AUTH_TOKENYOUR_API_KEY export ANTHROPIC_MODEL模型广场里的模型 ID配好后在仓库根目录启动claude。先做一次最小连通性确认再进入读代码环节curl -sS https://taotoken.net/api/v1/messages \ -H x-api-key: YOUR_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d {model:模型广场里的模型 ID,max_tokens:64,messages:[{role:user,content:只回复 ok}]}注意 curl 这里写的是完整路径/api/v1/messages而 settings.json 里只写到/api——两者不矛盾前者是手动调用的完整端点后者是交给 SDK 自动补全的 Base URL。4. 让 Claude Code 交叉读两个 loss 文件连通之后把工作目录切到openclaw-combine/与openclaw-opd/的父目录用一条明确的指令让模型同时读两份文件并要求它以表格形式输出对照结果。可以这样下指令读 openclaw-combine/combine_loss.py 和 openclaw-opd/topk_distillation_loss.py。 对每个文件回答 1) advantage 的计算表达式逐项列出 2) teacher 侧 log-prob 的数组形状与索引方式是 [pos][k] 还是 per-token 标量 3) student 侧 log-prob 从哪个变量取 4) OPD 样本的 reward 被设成什么值RL 样本的 teacher_log_probs 被设成什么值 5) 说明这两处设定如何让两个分支在同一份 loss 里互不干扰。 不要改写文件只做只读分析并标注你引用的行号。这一步的价值在于把人工在两份文件之间来回映射数组变成一次结构化的对照。模型会把combine_loss.py里合并后的 advantage 表达式展开成RL 项 OPD 项两项并指出各自的权重来源同时对topk_distillation_loss.py里distill_token_ids/distill_logprobs的二维结构给出索引语义。你要重点盯三个答复点一是 OPD 样本的 reward 取值。当 OPD 样本的 reward 被置为 0 时同一个 group 内的标量奖励全部相同GRPO 那一支的组内归一化优势自然退化为 0RL 分支对这批样本的梯度贡献被消掉样本的主导权交给 teacher−student 的逐 token 差异。二是 RL 样本的teacher_log_probs取值。当它被设置为与rollout_log_probs相等时teacher 项逐 token 相减约等于 0OPD 分支对这批样本基本不产生推力advantage 完全由 PRM 标量奖励主导。三是两者的判定入口。这两个置 0 / 置等不是随机发生的而是由 combine server 的调度结果决定的hint 被接受且 eval 给到 ±1 的 turn 才有两项叠加只有 hint 被接受才有 OPD 信号只有 eval 给到 ±1 才有 RL 信号两者都不满足的 turn 直接丢弃。把这张判定表跟 loss 里的两处赋值对上才算真正解释了两个分支如何解耦。如果你希望模型把判定路径也画成清单可以追加一句对每个 turn 类型列出 reward、teacher_log_probs、loss_mask 三个字段的期望取值并指出在当前代码中各由哪一行赋值。这样得到的输出可以直接拿去和运行时打印的样本字段做比对。5. teacher log-probs 对不上时的常见错误与排查顺着上面三个答复点往下查遇到的具体问题大致分五类。第一类Base URL 形态错误导致的通道问题容易和公式对不上混淆。典型症状是 Claude Code 一发请求就报 404 或路径重复。检查两点ANTHROPIC_BASE_URL是否误写成https://taotoken.net/api/v1以及是否误填了官网首页那条带utm_*参数的地址。这两种写法都会让 SDK 拼出错误端点。判断方法很简单把 Base URL 换成https://taotoken.net/api后重启claude若对话恢复即为此类问题与 loss 文件无关。第二类取数取成了 teacher 的 top-1。在topk_distillation_loss.py里distill_logprobs[pos][k]是二维的如果合并阶段拿到的是每一行最大值等价于只保留 teacher 最偏好的 tokenstudent 实际 token 的分数被丢弃逐 token 优势会整体偏正且方差很小。排查方式是打印某个 position 上 k 轴的全部取值确认最终参与计算的那一列对应的是 student 的 token id而不是 natsort 后的第 0 列。第三类position 轴错位。核对方法是在 teacher 侧输出里定位第一个 response token 的位置索引与 rollout 阶段记录的 response 起始位置比较差值这个差值应当等于 hint 部分的 token 长度。若差值不等于 hint 长度说明 enhanced prompt 的拼接方式与预期不一致可能是分隔符被吞掉或引入了额外换行。第四类loss_mask覆盖区间过宽或过窄。过宽会把 prompt 段计入advantage 被稀释过窄会把 response 尾部截掉长回答的后半段没有监督。用一条运行时检查即可确认统计loss_mask中 1 的数量与 assistant 回复的实际 token 数比对。第五类权重环境变量未生效。合并时的加权系数默认都是 1如果通过环境变量调过单侧权重而进程未重新加载会出现某一侧信号看上去完全没进来的错觉。确认启动日志里打印的两个权重值与预期一致再判断是不是公式本身的问题。这五类里只有第一类属于通道配置问题其余四类都要回到源码和运行时打印上解决。把通道单独撇清之后排查范围会明显收窄。6. 把这条排障链路固定下来从终端里反复 grep换成让模型同时读combine_loss.py和topk_distillation_loss.py之后最大的变化是数组形状与索引语义的对照不再依赖人眼记忆你要的判断只剩三句话——OPD 样本的 reward 是不是 0、RL 样本的 teacher_log_probs 是不是等于 rollout_log_probs、这两处赋值各由哪一行完成。对上之后A_t 的两种来源就在同一份 loss 里自然分开了。Key 的创建与轮换在 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopd_teacher_logprobs_api_keys 管理Claude Code 的ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_MODEL三件套的完整填法与目录级覆盖方式见 https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentopd_teacher_logprobs_cc_doc 。把这两个链接里的事项走完下一次再遇到逐 token 优势方向不对就可以直接从第 4 节那张对照表开始查。
返回列表