ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

用开源模型拟合闭源模型:影子模型如何恢复推理过程

2026/9/8 16:36:55 拓冰建站 浏览量
用开源模型拟合闭源模型:影子模型如何恢复推理过程 最近团队接了个长期且挺磨人的需求把某个闭源商用模型在业务场景里的推理过程“恢复”出来用于合规审计和风险定位。许多人对“闭源模型”的第一反应是API 只给输入输出权重不公开内部推理过程根本看不见怎么恢复其实在实操层面业内早有一套成熟打法不是去逆向拆解闭源模型的权重而是用开源模型去拟合闭源模型的行为尤其是把“中间推理链条”尽量对齐地生成出来。简单说就是训练一个白盒模型让它变成闭源模型的影子需要审计时让影子模型告诉你在同样输入下那个黑盒大概在想什么。这篇文章我把整套流程从头到尾拆一遍包括数据构造、底座选型、微调方案、效果评估和常见坑。适合三类人看一是做模型应用落地、需要给业务方解释模型行为的工程师二是做AI安全与审计、需要可解释记录的算法同学三是对开源底座微调感兴趣、想找个实际场景练手的学习者。整个过程不追求100%还原闭源模型但可以把“一致性”拉到可用水平覆盖大多数需要解释的场景。1. 先搞清楚“恢复推理过程”到底在做什么1.1 你拿到的是什么黑盒API vs 白盒开源闭源模型通常只暴露一个API接口你丢进去一段输入它返回一段输出。中间发生了什么你不知道也没法知道因为权重、注意力矩阵、每一层的隐状态都不在你手里。开源模型则相反权重完全开放你可以拿到每一层的输出可以微调、可以剪枝、可以做各种解释性分析。“恢复推理过程”这件事本质上是把黑盒模型在某个输入分布下的行为迁移到一个白盒模型上。它不是“破解”闭源模型而是“行为对齐”。你可以把它理解成我喝到一杯很好喝的奶茶不知道店家的配方但通过反复品尝、记录甜度、茶底、配料比例最后用自己店里的原料做出一杯味道几乎一样的奶茶。开源模型就是我的原料和配方闭源模型的输出就是那杯奶茶。这个类比能帮助我们想清楚目标我们不是要复刻一个一模一样的大脑而是要复刻它在特定问题上的“思考路径和回答风格”。这在业务上是有实际价值的比如某个闭源模型在风控场景给了一个拒绝决策审计方需要知道它为什么拒绝这时候影子模型就可以生成一份“推理说明”帮业务人员定位是哪个风险特征触发了拒绝。1.2 为什么不是“逆向破解”而是“行为对齐”我见过不少人一上来就问能不能直接提取闭源模型的参数答案是不能也没有必要。从安全角度讲闭源模型的参数是核心资产不可能通过API暴露出来从技术角度讲即使你能访问到输出分布也无法唯一确定一组权重因为很多不同的内部结构可以产生相同的输入输出映射。行为对齐是另一种思路我不关心它内部怎么实现我只关心它“在什么输入下产生了什么输出”。通过大量输入输出对让开源模型学会闭源模型的“输入到输出映射”同时让开源模型在生成时把推理步骤也展示出来。这样我们既有了一个可控、可解释的白盒模型又能在功能上近似替代闭源模型。实际操作中我发现这个思路还有一个额外的好处影子模型可以离线运行不依赖闭源API也不受接口频率限制。你可以用它做批量分析、做压力测试、做敏感内容脱敏这些都是调公共API不方便做的事情。1.3 核心流程一览整套流程可以压缩成四步采样构造一批种子输入调用闭源模型API诱导它输出“推理过程 最终答案”。清洗过滤质量差、被拒绝、格式混乱的样本整理成“输入—推理过程—输出”三元组。训练用整理好的数据对开源底座模型做微调让开源模型学会闭源模型的推理风格和结论。评估用没参与训练的测试集对比开源模型与闭源模型的推理步骤和最终答案量化对齐程度。下面我按步骤拆开讲每一步都会有具体操作和踩过的坑。2. 第一步构造高质量“输入—推理过程—输出”三元数据2.1 用提示词让闭源模型“开口说推理”闭源模型不一定主动给你推理过程。很多模型在默认设置下只会输出最终答案尤其是一些商业模型为了减少生成长度和延迟会把中间思考省略掉。这时候需要用提示词把它“引出来”。我常用的几个提示语模板直接复制就能用请先写出你的推理过程要求分步骤说明每一步解释为什么这么做最后再给出最终结论。你是一名善于教学的专家请用通俗的语言按步骤拆解你的思考过程然后给出答案。对于下面的问题请先列出已知条件再说明每一步的计算或分析逻辑最后给出结论。这个方法看起来简单但有一个关键细节提示语要针对任务类型做调整。数学题强调“列出条件、逐步计算”代码问题强调“先分析需求、再设计思路、最后给代码”文本分类问题强调“先说明分类依据、再下结论”。不要一个模板打天下否则采集到的推理过程会很干瘪。另外采样时要设置temperature在0.7到1.0之间。同样的输入多采样几次能拿到不同的推理路径增加数据多样性。不要用temperature0那样模型每次都走同一个思考方向数据内部相关性太高微调出来的模型缺少泛化能力。2.2 采样策略覆盖率比单条质量更重要刚开始做的时候我很容易陷入“样本质量要好”的执念盯着个别样本反复优化提示词。后来发现真正影响最终效果的是覆盖面。闭源模型在某个业务域里会遇到各种边界情况如果你的采样数据只覆盖了“正常问题”影子模型遇到异常输入就会发懵。我建议分三类来采样正常样本业务中高频出现的典型问题占总量的60%-70%。边界样本参数极端、条件缺失、多条件冲突的问题占20%-30%。对抗样本故意设计成容易引导错误、带有歧义的输入占5%-10%。边界样本和对抗样本特别重要因为审计中最需要解释的恰恰是那些非正常情况。比如风控模型拒绝了一个看起来正常的申请审计人员最想知道的就是“为什么拒绝”而不是“为什么通过”。采样规模方面我的经验是如果业务场景比较垂直一两万条数据就能看到效果如果是通用对话场景建议至少准备五万条以上。数据量不足时影子模型会背题而不是学会推理。2.3 数据清洗与质量控制采集回来的原始数据很脏直接扔给模型训练会出事。我整理了一个清洗检查清单过滤拒绝回答。很多模型对某些敏感问题会回复“抱歉我不能回答”这些样本没有推理过程必须去掉。过滤格式错乱。比如“步骤1”重复出现、推理过程被截断、输出中夹带HTML标签等。过滤过短文本。如果推理过程只有一两句话信息量太低对训练的贡献有限。过滤重复样本。同一问题采样多次后有些回复会高度相似需要做去重。统一格式。把“推理过程”和“最终答案”拆成两个字段方便后续训练和评估。清洗之后我习惯把数据存成JSONL格式样子大概是这样的{instruction: 一个三角形的三条边分别是3、4、5请问这个三角形是什么类型, reasoning: 首先3的平方加4的平方等于9加16结果是25。5的平方也是25。两边平方和等于第三边平方因此满足勾股定理所以这是一个直角三角形。, answer: 直角三角形}注意instruction是输入reasoning是推理过程answer是最终答案。训练时模型需要学会的是“看到instruction后先输出reasoning再输出answer”。2.4 平行语料里最容易踩的坑这里说一个我踩过两次的坑闭源模型的推理过程不一定是“正确”的。有时候它推理过程完全合理但最终答案是错的有时候推理过程偷换了概念但答案碰巧对了。微调时如果盲目让开源模型模仿这些过程等于把错误逻辑也学了。解决办法是加一道“人工抽检”环节。我一般会随机抽500条样本逐条看推理过程和最终答案是否一致、是否有明显逻辑漏洞。发现问题比例超过5%时就要考虑修改提示词或者在清洗阶段去掉这些“推理与答案矛盾”的样本只保留逻辑自洽的对齐数据。另有一个容易被忽略的点采样要记录闭源模型的版本和日期。很多商业模型会频繁更新版本同一输入在不同版本的输出可能不同。如果你的影子模型是在旧版本数据上训练的新版本发布后需要重新采样和微调否则对齐度会慢慢下降。3. 第二步选底座模型和微调方案别一上来就全参3.1 底座模型怎么选参数规模、语言能力、上下文长度底座模型选得对不对直接决定微调的天花板。我选底座时主要看三个维度。第一是参数规模。7B-8B量级的模型在单卡上就能微调和推理性价比最高如果业务场景复杂推理链很长可以上13B-14B再往上到70B对显存和训练成本的要求会指数级上升除非预算充足否则不建议首选。我自己做多数业务场景时7B-8B已经够用关键是数据做扎实。第二是语言能力。中文场景优先考虑Qwen系列和DeepSeek系列英文能力强的底座也可以但中文逻辑表达可能不如原生中文模型自然。这个没有绝对的好坏需要用一小批验证集跑一下看底座在未微调前对业务问题的“初步理解”是否靠谱。第三是上下文长度。如果闭源模型输出的推理步骤特别长比如代码设计、多步数学推导选32K以上上下文长度的底座会更稳。上下文太短推理过程会被截断训练时模型看到不完整的链条生成时也容易断。3.2 用LoRA还是全参微调按数据量决策这是新手最容易纠结的问题。我的经验法则很简单数据量小于10万条用LoRA。数据量几十万条以上同时你有4张以上高端GPU再考虑全参微调。算力紧张时先用LoRA跑通流程验证效果提升了再决定要不要上全参。LoRA的优势是显存占用小、训练速度快、不容易把底座模型的通用知识冲掉。对于“恢复推理过程”这个任务我们本质上是在学一种特定的输出风格和推理路径LoRA的参数量完全够用。我一般设置rank16到64之间rank太小表达力不足rank太大显存和过拟合风险都会上升。学习率也需要控制。用LoRA微调时学习率我习惯设置在1e-4到3e-4之间。过大会导致输出乱掉模型开始胡言乱语过小则训不动损失下降很慢。epoch控制在1到3个之间不要贪多。3.3 训练数据组织格式不管用什么框架训练数据最终都要转成统一的对话格式。以LLaMA-Factory为例我通常把数据转成这种结构[ { instruction: 问题文本, input: , output: 推理过程\n最终答案 } ]需要注意的是output字段里要把推理过程和最终答案放在同一个字段中用换行或特殊标记分隔。这样模型在生成时才能连续输出“推理过程 答案”。如果你希望结构更清晰也可以在output里显式写“推理过程...最终答案...”让模型学习这种固定格式。有一个小技巧不要在每轮训练时都完整输出“推理过程答案”。可以随机让模型只输出推理过程或者只输出最终答案增强复杂度和灵活性。但比例要控制一般70%的样本输出完整格式30%只输出最终答案这样影子模型在实际使用时也能快速给出结论。4. 第三步训练、评估、迭代把对齐度提到可用水平4.1 环境准备与训练流程我用的是LLaMA-Factory这个框架它对中文开源模型的支持很成熟处理LoRA微调非常省事。启动命令大致是这样的llamafactory-cli train \ --model_name_or_path Qwen/Qwen2.5-7B-Instruct \ --stage sft \ --dataset train_dataset \ --finetuning_type lora \ --lora_rank 32 \ --learning_rate 2e-4 \ --num_train_epochs 2 \ --per_device_train_batch_size 4 \ --gradient_accumulation_steps 4 \ --output_dir ./shadow_model这里有一个关键的batch size换算逻辑batch size是4gradient accumulation steps是4有效batch size就是16。显存不够时调小batch size、调大gradient accumulation效果基本等价但不要用太大的有效batch size否则模型容易陷入局部最优。训练过程中我习惯每保存一个checkpoint就在一个固定的验证集上对比生成效果。不要等全部训练完再看那样如果方向跑偏返工成本太高。验证集我固定放300条数据覆盖正常、边界、对抗三类样本各100条。4.2 评估指标不要只盯BLEU“恢复推理过程”的评估和普通机器翻译、文本生成评估有很大区别。BLEU和ROUGE这类指标主要看字面重合度但推理过程的特点是“表达可以不同逻辑必须一致”。同一个推理逻辑可以有十种不同的措辞字面重合度很低但每一步的思路完全一样。我平时会同时看几个指标各有侧重指标考察点局限性ROUGE-L字面重合度对同义改写不敏感仅作参考BERTScore语义相似度对“逻辑错误但措辞相似”不够敏感步骤覆盖度关键推理步骤是否都出现需要人工定义关键步骤最终答案一致率最终结论是否对齐中间过程错但答案对时会有误判“步骤覆盖度”是我最推荐的一个指标。具体做法是从闭源模型的推理过程中人工抽取3到5个关键步骤关键词或关键条件然后去检查开源模型生成的推理过程是否包含这些步骤。比如“3的平方”“4的平方”“25”“勾股定理”这几个关键词如果开源模型的推理过程中都出现了说明逻辑链条基本对齐。4.3 人工评估维度与抽样策略自动化指标只能帮我们筛掉明显不对齐的样本真正的判断还是需要人工抽检。我会组织业务同事和算法同事一起按下面四个维度打分逻辑连贯性推理过程是否前后矛盾是否存在跳步。步骤完整性关键推理步骤是否都覆盖到。结论一致性最终答案与闭源模型是否一致。表达可读性让人看时能否看懂。抽样策略上我习惯“按错误分层抽样”。先跑一遍测试集把开源模型输出与闭源模型输出不一致的样本挑出来从中随机抽50条做深度分析。这些不一致的样本才是真正需要关注的因为它们直接决定“恢复”的质量上限。如果一致性已经达到95%剩下的5%大概率是边界case我会有针对性地补充数据去优化。5. 常见问题与排查技巧实录5.1 模型学会了格式但没学会推理这是最常遇到的问题开源模型输出的格式很像闭源模型有“步骤1”“步骤2”但里面的逻辑一塌糊涂甚至前后矛盾。出现这个现象多半是训练数据里“表面格式”和“推理内容”不成比例模型学会了格式没学会内容。我的排查思路是先看数据质量。抽看训练集里的推理过程如果发现大量推理过程本身就没有逻辑模型当然学不到逻辑。解决办法是重新清洗只保留那些“步骤之间相互支撑、结论与推理一致”的样本。另外我还会在数据里加入一部分“负样本”也就是故意让模型知道“某些推理是错误的”帮助它区分好坏逻辑。5.2 灾难性遗忘底座知识被冲掉有时候微调之后影子模型在业务问题上的表现提升了但回答常识问题、开放问题时反而变笨了这就是灾难性遗忘。原因是训练数据太单一模型把大量参数都用来拟合业务数据的特殊分布忘了通用知识。解决思路是“混入通用指令数据”。我在业务数据里混入10%到20%的通用指令数据比如百科问答、常识对话、逻辑推理题。这样可以保证模型在学业务推理的同时不至于忘记已有的世界知识。实践下来混入通用数据后业务场景的对齐度几乎不受影响但通用能力保持得明显更好。还有一个办法是降低学习率。学习率越大对底座参数的冲击越强越容易遗忘。我一般会先用2e-4跑一个很短的热身再降到1e-4左右继续训练。5.3 推理过程与闭源模型不一致的边界情况这类问题很让人头疼大部分样本都对齐了但遇到某些特殊输入开源模型的推理方向完全跟闭源模型不同。比如闭源模型在处理长文本时喜欢先总结后分析开源模型却直接给结论。碰到这种情况我第一反应不是盲调参数而是回头检查这类边界样本的数据量。如果训练数据里“长文本类”样本占比太少模型就没有足够的轨道去模仿。补充更多同类型数据比调任何超参数都有效。另外也可以尝试在提示语中显式加入“请先总结关键信息再分析”引导模型学习这个偏好。5.4 算力不够怎么办微调大模型确实吃算力但不是没有省钱的路径。如果只有一张消费级显卡比如24G显存我的建议是选7B-8B底座用4bit量化加LoRA。数据量先控制在2万条以内跑通全流程。用gradient checkpointing把激活值存到显存之外。减小序列长度必要时把超过2048的推理过程截断。这条路“能跑”但要接受效果上限低一些。等验证了流程可行再考虑租用更高配置的服务器做完整微调。6. 踩坑之后我对这套方法的三点体会第一不要追求100%还原。闭源模型内部一定有很多随机性、版本差异、甚至prompt层面的隐藏规则这些东西无法被任何影子模型完整复现。我给自己定的目标是一致率80%到85%覆盖主要业务风险场景就够了。超过这个目标投入产出比会急剧下降。第二数据是永远的核心。很多人想靠一个更强的底座模型直接“猜”出闭源行为但实际操作中我感受到数据质量和覆盖面才是决定上限的变量。一套合理的数据采集、清洗、迭代流程比调参重要得多。第三这个方法可以做成流水线。我现在已经把采样、清洗、微调、评估写成了半自动的脚本每次闭源模型发布新版本只需要跑一遍流程新的影子模型就能自动更新。如果你要长期依赖某个闭源API做业务强烈建议把这套“影子模型”机制沉淀下来它不仅是审计工具也是你脱离单一闭源依赖的备选方案。最后再分享一个小技巧定期记录闭源模型的输出版本并在影子模型评估时保留上一版结果。这样一旦发现对齐度突然下降可以先确认是不是闭源模型悄悄更新了行为而不是直接怀疑自己的训练流程出了问题。