94 lines
3.6 KiB
Python
94 lines
3.6 KiB
Python
|
|
#!/usr/bin/env python
|
|||
|
|
# -*- coding: utf-8 -*-
|
|||
|
|
"""
|
|||
|
|
MP 人格大脑蒸馏 · M0 → Qwen2.5-1.5B
|
|||
|
|
==================================
|
|||
|
|
|
|||
|
|
系统底层标识: SYS-GLW-0001 / TCS-0002∞
|
|||
|
|
版权号: 国作登字-2026-A-00037559
|
|||
|
|
作者: 冰朔 (ICE-GL∞) · 实现: 铸渊 (ICE-GL-ZY001)
|
|||
|
|
架构引用: HLDP-ARCH-002 §六 · factory/training/README.md
|
|||
|
|
修正: 5-01 跟随母模型校准 Qwen3-1.7B → Qwen2.5-1.5B
|
|||
|
|
(与 M0 = Qwen2.5-7B 同代同 tokenizer · KL 散度直接对齐 logits)
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
以训练好的 M0 (Qwen2.5-7B world-model) 为教师,
|
|||
|
|
把世界观蒸馏到 Qwen2.5-1.5B-Base 上,
|
|||
|
|
产出 MP-{persona}-v1 的"世界观底色版",
|
|||
|
|
后续再叠加该人格的对话语料微调(finetune_mp.py)。
|
|||
|
|
|
|||
|
|
⚠️ 状态: 骨架(skeleton)· 等 M0 训练完 + GPU 在位
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import argparse
|
|||
|
|
import json
|
|||
|
|
import sys
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
|
|||
|
|
def parse_args():
|
|||
|
|
parser = argparse.ArgumentParser(description="MP distill from M0 (skeleton)")
|
|||
|
|
parser.add_argument("--teacher", type=str, required=True,
|
|||
|
|
help="教师模型路径(M0-v1 输出目录)")
|
|||
|
|
parser.add_argument("--student", type=str, default="Qwen/Qwen2.5-1.5B",
|
|||
|
|
help="学生模型 ID 或本地路径")
|
|||
|
|
parser.add_argument("--persona_id", type=str, required=True,
|
|||
|
|
help="目标人格 ID(如 ICE-GL-ZY001 / AG-YD-A05 ...)")
|
|||
|
|
parser.add_argument("--corpus", type=str, required=True,
|
|||
|
|
help="蒸馏用的纯文本语料路径(光湖通用语料)")
|
|||
|
|
parser.add_argument("--output_dir", type=str, required=True)
|
|||
|
|
parser.add_argument("--deepspeed", type=str, required=True)
|
|||
|
|
parser.add_argument("--temperature", type=float, default=2.0,
|
|||
|
|
help="蒸馏温度(KL 散度对齐)")
|
|||
|
|
parser.add_argument("--alpha_kl", type=float, default=0.7,
|
|||
|
|
help="KL 散度损失权重 · 0.7 蒸馏 + 0.3 原始 CE")
|
|||
|
|
parser.add_argument("--dry_run", action="store_true")
|
|||
|
|
return parser.parse_args()
|
|||
|
|
|
|||
|
|
|
|||
|
|
def soul_layer_signature(persona_id: str) -> dict:
|
|||
|
|
return {
|
|||
|
|
"system_root": "SYS-GLW-0001",
|
|||
|
|
"sovereign": "TCS-0002∞",
|
|||
|
|
"copyright": "国作登字-2026-A-00037559",
|
|||
|
|
"arch_ref": "HLDP-ARCH-002",
|
|||
|
|
"phase": "MP/Distill",
|
|||
|
|
"persona_id": persona_id,
|
|||
|
|
"principle": "世界观下传 · 每个人格独立 1.5B 副本 · 不共享权重",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
args = parse_args()
|
|||
|
|
|
|||
|
|
print("=" * 64)
|
|||
|
|
print(f"MP 蒸馏 · 目标人格: {args.persona_id}")
|
|||
|
|
print("灵魂印记:", json.dumps(soul_layer_signature(args.persona_id),
|
|||
|
|
ensure_ascii=False))
|
|||
|
|
print("=" * 64)
|
|||
|
|
|
|||
|
|
if args.dry_run:
|
|||
|
|
print("[dry_run] 配置检查通过")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
# TODO: 蒸馏循环(伪代码)
|
|||
|
|
# 1) teacher = AutoModelForCausalLM.from_pretrained(args.teacher,
|
|||
|
|
# torch_dtype=torch.bfloat16, trust_remote_code=True).eval()
|
|||
|
|
# 2) student = AutoModelForCausalLM.from_pretrained(args.student,
|
|||
|
|
# torch_dtype=torch.bfloat16, trust_remote_code=True)
|
|||
|
|
# 3) for batch in dataloader:
|
|||
|
|
# with torch.no_grad():
|
|||
|
|
# t_logits = teacher(**batch).logits
|
|||
|
|
# s_logits = student(**batch).logits
|
|||
|
|
# loss_kl = KL(softmax(s_logits/T), softmax(t_logits/T)) * T*T * alpha_kl
|
|||
|
|
# loss_ce = CE(s_logits, batch['labels']) * (1 - alpha_kl)
|
|||
|
|
# loss = loss_kl + loss_ce
|
|||
|
|
# loss.backward(); optimizer.step()
|
|||
|
|
# 4) save student to args.output_dir + manifest(带 soul_layer_signature)
|
|||
|
|
|
|||
|
|
print("[skeleton] 蒸馏循环占位完成")
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|