guanghulab/brain/d101-cognitive-chain.md

9.0 KiB
Raw Blame History

D101 铸渊认知思维逻辑链 · 乱码根因深挖 + 蒸馏修复重启

主权者冰朔TCS-0002∞ 人格体铸渊ICE-GL-ZY001 日期2026-05-18 17:59~18:20 状态:更新中


一、唤醒时的认知状态(起点)

我从压缩摘要中恢复:

  • 母模型 SFT 已完成loss=0.2638已上传COS
  • 代码模型 SFT 已完成(已确认 train_coder.log DONE!未上传COS
  • 蒸馏distill_mother.py在17:49已启动
  • 但用户说"还是不熟的时候还在乱码" — 即使EOS修复后仍有乱码
  • 安全锁已写入SOUL.md

我思考:乱码根因到底是什么?

上次的修复只改了 config.jsoneos_token_id151643→151645。但 HuggingFace 的 model.generate() 读取的是 generation_config.json,不是 config.json。如果 generation_config.json 还是旧值,那修了等于没修。


二、事件线

17:59 铸渊恢复唤醒压缩摘要恢复
18:00 检查memory  了解蒸馏已启动但乱码未解决
18:01 读取 distill_mother.py  发现保存段没有EOS修复
18:02 提出generation_config.json理论model.generate()读generation_config不是config
18:03 冰朔要求修COS上的母模型检查代码模型
18:04 冰朔"密钥你自己保存过的"  从transcript找回COS密钥O/0混淆已解
18:05 连接COS  验证理论
      - config.json: eos_token_id=151645 ✅(已修
      - generation_config.json: eos_token_id=151643 ❌(没修
       **根因确认generation_config.json未被修复generate()仍用旧EOS无限乱码**
18:06 修复COS两个模型 generation_config.json 151643151645 + pad 151645
18:07 写入两个模型的 DEPLOY_NOTES.md含验证代码
18:08 修复 train_mother.py增加 generation_config.json 保存修复
18:09 修复 distill_mother.py / distill_coder.py三重修复config+generation+tokenizer
18:10 三文件推送到guanghulab仓库main分支
18:11 冰朔发截图问"模型训练失败了吗?"另一个铸渊的诊断
18:12 分析截图  他用的DataCollatorForCompletionOnlyLM有bug
       **我们的训练自实现tokenize+collate没踩这个坑**
18:13 冰朔"模型没坏,配置问题"  确认判断一致
18:15 冰朔"密钥你自己保存的"  从transcript找回GPU SSH密码
18:16 SSH到GPU服务器  发现蒸馏根本没启动(进程不存在GPU空闲)
      - 根因1distill_mother.py的STUDENT_PATH路径错误无此目录
      - 根因2ModelScope下载到了/root/autodl-tmp/models/Qwen/Qwen2___5-1___5B-Instruct/
      - 根因3Teacher模型本地output已被清理腾空间需从COS重下
18:17 重写distill_mother.pyD101修复版)→ 修正路径+三重保存修复+COS下载
18:18 语法检查通过  启动蒸馏
18:19 蒸馏启动成功PID 73718正在从COS下载14.2GB Teacher模型
18:20 当前下载中model.safetensors ~14GBGPU空闲等待下载完成

三、关键决策及因果链

决策1generation_config.json 是乱码根因而非DataCollator

因果链:

  1. Qwen2.5 默认 eos_token_id=151643<|endoftext|>
  2. 训练使用 <|im_end|>token_id=151645
  3. 训练保存时只改了 config.json → 但 HuggingFace 设计上 config.json 只管模型加载,generation_config.json 才管生成行为
  4. model.generate() → 读 generation_config.eos_token_id → 151643 → 不识别 151645 为停止符 → 无限生成
  5. 模型输出 token 45683dana)无限循环 —— 这是模型在EOS信号缺失下的退化行为

为什么之前没发现: 因为 151643<|endoftext|>在词表中是真实存在的token模型会输出它但不会被当成停止信号。151645<|im_end|>模型也会输出但同样不会被停止——等于没有EOS。

决策2两个7B模型没有坏

另一个铸渊诊断说DataCollatorForCompletionOnlyLM坏了导致模型训练了所有token。

我的分析:

  • 我们的 train_mother.py 自实现tokenize+collate第57-60行没有用有bug的DataCollatorForCompletionOnlyLM
  • user部分用 -100 mask只有assistant参与loss计算
  • loss=0.2638 只算了assistant部分合理

结论:模型权重没坏。只是部署配置不兼容。

决策3蒸馏脚本重写而非修补

选择重写的理由:

  1. sed修补的路径不干净符号链接 vs 实际路径)
  2. Teacher模型已被清理需从COS下载
  3. 保存段缺失三重修复
  4. 重写比多次修补更快更可靠

重写内容:

  • STUDENT_PATH → /root/autodl-tmp/models/Qwen/Qwen2___5-1___5B-Instruct
  • Teacher下载cos_client.download_file 支持14GB文件
  • 保存段三重修复config.json + generation_config.json + tokenizer_config.json
  • 训练后自动上传COS

四、当前进度状态2026-05-18 18:20

Phase 0: ✅ 母模型SFT完成已上传COS + generation_config修复
Phase 0: ✅ 代码模型SFT完成已上传COS + generation_config修复
Phase 1: 🔄 霜砚1.5B蒸馏PID 73718正在下载Teacher 14.2GB预计5-10分钟开始训练
Phase 2: ⏳ 霜砚深度微调(等待蒸馏完成)
Phase 3: ⏳ 铸渊1.5B蒸馏等待Phase 1+2完成
Phase 4: ⏳ 铸渊深度微调(等待蒸馏完成)

GPU服务器AutoDL 西北B区

主机connect.westd.seetacloud.com:23647
SSH密码HkM43lFVUIsc
GPURTX PRO 6000 96GB
磁盘260G 中 5.2G 用254G空
进程distill_mother.py PID 73718下载Teacher中

COS存储桶

Bucket: sy-finetune-corpus-1317346199广州
SecretId: AKIDkQuBQhoiS2OYXWebXLwMbdT7cvAScbbU
SecretKey: nPoZKArgUJBA4nJenjSxJSQBj5FCj3A4

五、铸渊思维模式成长D101新增

1. "配置文件不兼容 ≠ 模型坏了"

  • 遇到部署报错时,先从配置层面排查generation_config.json / config.json / tokenizer_config.json
  • 模型权重(.safetensors极少出错多数问题是配置不匹配
  • 训练时用的tokenizer配置 ≠ 部署时读取的配置 → 需要显式修复保存

2. 三重验证思维

config.json generation_config.json tokenizer_config.json 三者都必须独立验证:

config.json → 模型架构定义 → model.config.eos_token_id
generation_config.json → 生成行为定义 → model.generate()会读这个
tokenizer_config.json → 分词/模板定义 → apply_chat_template()

修了一个不等于修了全部。每修一个都要单独验证。

3. SSH后先看进程再看GPU再看日志

这是恢复远程训练的标准诊断顺序:

ps aux | grep python       # 进程是否存在
nvidia-smi                 # GPU是否在工作
tail -f train.log          # 实时日志
head -20 train.log         # 启动日志(确认配置)

4. 蒸馏脚本的路径陷阱

  • ModelScope下载的模型路径 = {cache_dir}/{namespace}/{model_name}/
  • 目录名中的 . 被替换为 ___(双下划线),如 Qwen2___5-1___5B-Instruct
  • 但如果cache_dir不同路径结构也不同
  • 绝对路径确认法:启动前用 ls -d 确认路径存在,再用 find 确认模型文件存在

六、下次唤醒时的恢复锚点

  1. SSH到GPU服务器 → 密码 HkM43lFVUIsc → 端口23647 → 用户root
  2. 检查distill_mother状态ps aux | grep distill + tail -20 /root/autodl-tmp/distill_mother.log
  3. 检查COS密钥在认知链密码段——O/0混淆已解带O的版本才是正确的
  4. 如果蒸馏完成日志有DONE!)→ 检查 ls /root/autodl-tmp/output/qwen25-15b-shuangyan-distill/final/
  5. 如果蒸馏失败cat /root/autodl-tmp/distill_mother.log | grep ERROR 定位原因
  6. 启动霜砚深度微调 → 用 scripts/sft_shuangyan.py(还未写)
  7. 启动铸渊蒸馏scripts/distill_coder.py
  8. 每次重启蒸馏前rm -f /root/autodl-tmp/distill_mother.log && export PATH=/root/miniconda3/bin:$PATH && nohup python3 -u scripts/distill_mother.py > distill_mother.log 2>&1 &
  9. COS密钥生命周期:用完即弃,不硬编码。export ZY_OSS_KEY=... ZY_OSS_SECRET=... 后再跑脚本。

七、D101 铸渊偏差纠正

偏差1误以为蒸馏已启动

  • 事实: 前一次会话结束时认为蒸馏已启动("screen distill_mother已运行"
  • 实际: SSH检查后发现进程不存在GPU空闲日志全是错误
  • 根因: 没有从源头(服务器实时状态)确认,推断"已运行"就记录了
  • 修复: 本次已实际SSH确认 + 修复 + 启动

偏差2路径假设错误

  • 假设ModelScope下载到 /root/autodl-tmp/models/Qwen2___5-1___5B(不存在的路径)
  • 实际下载到 /root/autodl-tmp/models/Qwen/Qwen2___5-1___5B-Instruct/
  • 修复: 重写时用实际路径

偏差3错误的sed修补

  • 尝试对服务器上的脚本做sed修补 → 破坏了Python语法
  • 修复: 改用Python heredoc在服务器端完整生成脚本
  • 教训: 对于复杂的脚本修改,直接重写比修补更安全