Skip to main content

SaddleLLM

当前版本:2.36

SaddleLLM 是一个配置驱动、与行业无关的大模型全生命周期平台。用户准备数据、模型和一份训练配置,系统负责检查输入、安排训练阶段、调用对应训练器,并保存 checkpoint、评测结果、发布产物和运行状态。医疗、护理、教育等是外部领域项目,通过数据、配置或插件接入,不能成为核心包中的硬编码分支。

平台能力边界、成熟度和开发优先级见 通用大模型平台边界;完整命令与参数见 简明命令手册;本轮主链代码审查及后续缺口见 代码完善审查。

本文只讲当前实现,按三个问题展开:

  1. 这个系统是什么。
  2. 怎么使用,命令会返回什么。
  3. 代码和训练过程为什么这样运行。

1. 这个系统是什么

1.1 系统定位

SaddleLLM 不是一个单独的模型,也不是重新实现 PyTorch、Transformers、PEFT 或 TRL。它位于这些训练库的上层,把一次模型实验需要的内容组织起来:

数据 + 基础模型 + 训练参数 + 执行阶段
                    ↓
              SaddleLLM
                    ↓
训练计划 + checkpoint + 评测 + 发布文件 + 运行记录

它主要解决五件事:

  1. 用一份 YAML/JSON 明确本次运行要做哪些阶段。
  2. 在加载大模型前检查配置、数据和运行环境。
  3. 按顺序调用预训练、SFT、偏好训练、评测和导出等实现。
  4. 把前一个阶段产生的模型或数据交给后一个阶段。
  5. 保存计划、状态和结果,让失败可定位、运行可恢复、产物可追踪。

1.2 输入、处理和输出

类型 具体内容
输入 YAML/JSON 配置、文本或多模态数据、基础模型或 checkpoint
处理 数据检查、模型加载、阶段排序、训练、评测、导出
输出 阶段计划、训练 checkpoint、最终模型、指标、发布门禁、运行摘要

用于 train、validate-config 和 plan 的训练配置只有一种结构:顶层必须有非空的 stages 列表。

例如:

stages: [sft, preference, eval]

这表示依次执行:

监督微调 → 偏好训练 → 评测

每个阶段的参数放在同名配置块里:

stages: [sft, preference]

sft:
  enabled: true
  data_path: data/sft.jsonl

preference:
  enabled: true
  method: dpo
  data_path: data/preference.jsonl

1.3 当前支持的能力

领域 阶段或入口 当前实际行为
Tokenizer tokenizer 训练新 tokenizer;未提供训练参数时加载已有 tokenizer
从零预训练 pretrain + pretrain_mode: scratch 创建模型、处理语料、执行 causal LM 训练并保存最终模型
继续预训练 pretrain + pretrain_mode: continue 加载已有权重,用新训练任务继续优化
监督微调 sft 执行全参数、LoRA 或 QLoRA SFT
偏好训练 preference 执行 DPO、ORPO 或 KTO
RLHF rlhf DPO 可执行;PPO dry-run可规划,实际训练开始前明确阻断
多教师蒸馏 mopd 生成计划,或调用教师收集 on-policy 数据供后续 SFT
VLA vla_sft 检查并规范化机器人轨迹;vla.train: true 时执行行为克隆训练
通用图文训练 mllm_sft、vision_alignment 当前负责数据规范化和训练计划,还没有执行通用 VLM 参数优化
图像生成 media_cache + image_generation 编码图像与文本条件,训练潜变量生成模型
音乐生成 media_cache + music_generation 编码音频码本与文本条件,训练多码本自回归模型
视频生成 media_cache + video_generation 编码视频潜变量与文本条件,训练时空生成模型
世界模型 world_model 用离线轨迹训练 RSSM 或 categorical RSSM
眼动控制 eye_control 在安全软件仿真器中评估 PID 或世界模型规划控制
评测 eval 计算指标,并可按规则生成发布门禁结果
导出 export 打包 HF 或 Saddle 模型;可要求评测门禁先通过
外部算子 operator 调用已配置的 agent/大模型算子并登记产物

1.4 两种模型后端

model.backend 决定文本模型由哪套实现负责:

后端 用途 当前边界
hf Hugging Face 模型加载、SFT、LoRA、QLoRA、DPO、ORPO、KTO 最适合已有开源模型的后训练
saddle 项目原生模块化语言模型、原生 checkpoint、预训练和 DPO 不支持 LoRA/QLoRA;偏好方法当前只支持 DPO

非单进程的 DDP、FSDP 和 DeepSpeed 路径,目前只对 model.backend: saddle 的 pretrain 阶段声明为可执行。其他内置阶段使用 distributed.strategy: single。

1.5 代码目录

路径 作用
saddlellm/cli.py 命令行参数和命令分发
saddlellm/training/TrainingOrchestrator.py 解析配置、校验并执行阶段
saddlellm/framework/stages.py 阶段注册表和阶段能力声明
saddlellm/training/ 预训练、SFT、偏好训练和分布式运行
saddlellm/data/ 数据采集、清洗、规范化和检查
saddlellm/models/ 模型结构、构建、加载和 tokenizer
saddlellm/multimodal/ 图像、音频、视频、VLM 和 VLA
saddlellm/world_models/ RSSM 数据、模型、训练和推理
saddlellm/spatial/ 空间感知、路径规划、眼动控制和 WorldAgent
saddlellm/evaluation/ 评测、冒烟测试和发布门禁
saddlellm/runtime/ 模型导出、服务和部署
configs/ 可以直接参考的配置文件
tests/ 行为和接口测试

2. 怎么使用、命令做什么、返回什么

2.1 安装

建议使用独立虚拟环境:

python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e ".[posttrain,dev]"

按功能安装可选依赖:

需求 安装命令
通用训练 python -m pip install -e ".[train]"
SFT、PEFT、TRL python -m pip install -e ".[posttrain]"
QLoRA python -m pip install -e ".[posttrain,qlora]"
推理 API python -m pip install -e ".[serve]";运行时4/8bit量化再加qlora:.[serve,qlora]
空间智能与眼动控制 python -m pip install -e ".[spatial]"
开发和测试 python -m pip install -e ".[dev]"

如果要严格使用仓库验证过的后训练版本:

python -m pip install -r requirements-posttrain.txt

安装完成后确认命令可见:

saddlellm --help

也可以不用 console script:

python -m saddlellm.cli --help

2.2 第一次运行

创建一个 10 步 LoRA SFT 小项目:

saddlellm quickstart ".\my-training"

生成的目录:

my-training/
├─ config.yaml
├─ README.md
└─ data/
   └─ sft.jsonl

命令返回 JSON,主要字段如下:

{
  "workspace": "绝对路径/my-training",
  "config": "绝对路径/my-training/config.yaml",
  "stages": ["sft"],
  "model": "Qwen/Qwen2.5-0.5B-Instruct",
  "data_files": {"sft": "绝对路径/my-training/data/sft.jsonl"},
  "created_files": ["..."],
  "next_steps": ["..."],
  "note": "..."
}

进入目录后依次执行:

Set-Location ".\my-training"
saddlellm doctor
saddlellm inspect-data data/sft.jsonl --task sft
saddlellm validate-config config.yaml
saddlellm train config.yaml --dry-run
saddlellm train config.yaml

正式训练有独立 validation/test 时,一次完成 schema 与跨集合泄漏检查:

saddlellm inspect-data data/train.jsonl --task sft `
  --validation-data data/validation.jsonl `
  --test-data data/test.jsonl `
  --group-field case_id --strict-leakage `
  --output outputs/split_audit.json

同一 group、规范化后的同题会阻断;高相似改写默认警告,--strict-leakage 下也会阻断。 报告默认对 group id 做哈希且不复制题目原文;只有在确认数据可安全展示时才使用 --include-content-previews。当配置含独立 validation_data_path 时,validate-config 和正式 训练前置检查也会自动执行训练/验证泄漏审计。

训练启动后,可在另一个终端查看进度、loss 曲线、阶段状态和日志:

saddlellm dashboard outputs/my-sft --open

dashboard 只读取训练目录中的标准产物,不占用第二份模型显存,也不要求安装单独的前端工程。历史训练目录同样可以打开。

创建“SFT 后接 DPO”的项目:

saddlellm quickstart ".\my-training" --stages sft,preference --preference-method dpo

使用自己的数据和模型:

saddlellm quickstart ".\my-training" --model "D:\models\my-model" --data "D:\datasets\sft.jsonl"

quickstart 不会下载模型,也不会开始训练。它只创建配置、示例数据和下一步命令。目标文件已存在时默认拒绝覆盖;--force 只覆盖它负责生成的文件。

2.3 直接训练,或者使用配置文件

最常见的单阶段 SFT 可以直接写命令,不必先创建 YAML:

saddlellm train sft `
  --model Qwen/Qwen3-0.6B `
  --data train.jsonl `
  --epochs 1 `
  --output-dir outputs/my-sft

完全等价的显式写法是:

saddlellm train --stage sft `
  --model Qwen/Qwen3-0.6B `
  --data train.jsonl `
  --epochs 1 `
  --output-dir outputs/my-sft

直接训练默认使用 LoRA、有效 batch 由 --batch-size 1 和 --gradient-accumulation-steps 4 组成、最大长度 512,并保留 5% 数据作内部验证。常用覆盖参数:

saddlellm train sft --model MODEL --data DATA `
  --method lora `
  --learning-rate 5e-5 `
  --batch-size 1 `
  --gradient-accumulation-steps 8 `
  --max-seq-length 384 `
  --max-steps 150 `
  --save-steps 50 `
  --eval-steps 50 `
  --precision bf16 `
  --local-files-only `
  --output-dir outputs/my-sft

正式训练建议准备独立验证文件,避免随机划分把同源病例或同一对话的不同轮次分到两边:

saddlellm train sft --model MODEL --data train.jsonl `
  --validation-data validation.jsonl `
  --method lora --lora-target-modules all-linear `
  --save-steps 50 --eval-steps 50 `
  --output-dir outputs/my-sft

--validation-data 与 --validation-split 二选一。存在验证集时,SaddleLLM 按 eval_loss 记录并在训练结束恢复最佳 checkpoint;按 step 验证时,--save-steps 必须是 --eval-steps 的整数倍。结果中的 best_model_checkpoint 和 best_metric 是实际选择证据。

--method 支持 lora、qlora 和 full。--lora-target-modules all-linear 使用 PEFT 的 架构无关写法覆盖模型中适合 LoRA 的全部线性层,通常比只训练 Q/K/V/O 投影有更大的适配容量, 也会增加可训练参数、显存和耗时;仍可用逗号明确指定层。用 --dry-run 只显示解析后的完整配置 而不训练;实际训练时 SaddleLLM 会把等价配置保存为输出目录中的 command_config.json,保证 命令行训练仍可复现。

训练中断后,保持原输出目录、模型、数据、更新方法、batch 和并行规模不变,提高总 --max-steps,再加不带路径的 --resume-from-checkpoint,会自动选择最新 checkpoint:

saddlellm train sft --model MODEL --data DATA `
  --method lora --batch-size 1 --max-steps 300 `
  --output-dir outputs/my-sft --resume-from-checkpoint

也可以在该参数后显式给出 checkpoint-* 路径。直接命令的精确续训一次只允许一个阶段; 多阶段恢复使用 YAML 的 pipeline.resume。SaddleLLM 会拒绝有效训练 batch 发生变化的“伪续训”。 结果同时记录 resumed_from_checkpoint、原始累计 train_metrics、不受续训步数稀释的 latest_train_metrics,并在存在内部验证集时保证写出最终 eval_metrics。

已有模型做领域继续预训练,也可以直接运行:

saddlellm train pretrain `
  --model Qwen/Qwen3-0.6B `
  --data data/nursing_corpus.jsonl `
  --text-column text `
  --max-steps 1000 `
  --global-batch-size 32 `
  --output-dir outputs/nursing-cpt

这是 pretrain_mode: continue:网络结构和 tokenizer 从 --model 继承,数据每行采用 {"text":"连续的护理教材或规范正文……"}。从零创建网络时建议改用 YAML 的 model.config + model.blueprint,因为网络结构属于模型身份,应该完整保存和审计,而不是堆成一长串命令行参数。

不确定后训练数据该用哪种方法时,使用名称明确的 auto-posttrain(不是含义模糊的 auto):

saddlellm train --stage auto-posttrain `
  --model Qwen/Qwen3-0.6B `
  --data data/posttrain.jsonl `
  --dry-run

它先抽样并检查本地数据,再按数据契约选择:instruction/output、messages 或普通 prompt/completion → SFT;prompt/chosen/rejected → DPO;带显式二元 label 的 prompt/completion → KTO。结果会输出 selected_stage、选择理由、质量警告和完整检查报告。 PPO 永远不会被自动选择;混合格式、未知格式、只有单一正负标签的 KTO 数据会直接拒绝, 避免静默丢样本。确认 dry-run 结果后去掉 --dry-run 即可训练。

auto-posttrain 只处理后训练,绝不会选择预训练。两者边界如下:

入口 数据形态 目标
pretrain / pretrain_mode: continue 大规模连续文本语料 学习语言、通用或护理领域知识
auto-posttrain 带目标回答或偏好标签的样本 自动选择 SFT、DPO 或 KTO,塑造回答方式与偏好

直接命令也支持有序的多阶段训练。--stage 中的逗号表示严格的先后依赖,不是无序开关;前一阶段成功保存的模型自动成为后一阶段输入:

saddlellm train --stage sft,kto `
  --model Qwen/Qwen3-0.6B `
  --data data/sft.jsonl `
  --kto-data data/kto.jsonl `
  --batch-size 2 `
  --output-dir outputs/sft-kto

这里 --data 属于第一个阶段,后续阶段分别使用 --dpo-data、--orpo-data、--kto-data 或 --ppo-data。当前直接命令可真实执行 SFT、DPO、ORPO、KTO,一条命令内最多包含一个 DPO/ORPO/KTO 阶段。PPO 名称已经纳入有序解析和 dry-run,但稳定执行器尚未接入;实际命令包含 PPO 时会在任何训练开始前失败,绝不会跳过 PPO 后继续执行后续阶段:

saddlellm train --stage sft,ppo,kto `
  --model MODEL `
  --data data/sft.jsonl `
  --ppo-data data/ppo.jsonl `
  --kto-data data/kto.jsonl `
  --dry-run

dry-run 会同时展示用户阶段 sft → ppo → kto、内部映射 sft → rlhf → preference,以及每个阶段的 needs 依赖。真正接通 PPO 前必须明确奖励模型、价值模型、rollout 策略和安全验证过的奖励契约,不能用“计划成功”冒充训练成功。

2.4 蒸馏与轻量化命令

轻量化不是一个模糊开关。SaddleLLM 将“得到更小学生模型”“持久化 CPU INT8”“GPU 加载时量化”和“稀疏权重实验”拆成职责清楚的命令:

目标 命令 当前稳定边界
更小的学生模型 saddlellm distill --mode logits ... 本地 teacher logits + 正确 causal mask,保存可直接加载的 HF 学生模型,并记录参数缩减与前后 PPL
用教师答案训练已有学生 saddlellm distill --mode data ... 在线教师只生成待审核 JSONL;审核后用 --teacher-data 执行 SFT,防止错误医疗答案直接回灌
持久化 CPU 模型 saddlellm quantize ... 动态 INT8;lightweight 是同义入口;产物可由 serve --device cpu 加载
GPU 低显存推理 saddlellm serve ... --quantization 8bit/4bit bitsandbytes 加载时量化,不另建模型目录
稀疏权重研究 saddlellm prune ... 产物可加载,但普通 dense 后端不保证文件更小或推理更快,必须另做效果评估

本地 logits 蒸馏会从教师配置创建层数和宽度更小的学生,同时使用真实标签 loss 与 teacher KL loss:

saddlellm distill --mode logits `
  --teacher E:\models\Qwen3-4B `
  --data data\nursing_corpus.jsonl `
  --eval-data data\nursing_validation.jsonl `
  --student-layers 12 --student-hidden-size 1024 --student-heads 16 `
  --max-steps 1000 --batch-size 1 --max-seq-length 1024 `
  --output-dir outputs\nursing-student

先加 --dry-run 可查看最终参数。该模式训练时需同时保留教师和学生,显存不够时应改用 data 模式。学生必须比教师小;不满足时命令会拒绝。输出报告包含 parameter_reduction_ratio、teacher/学生初始/学生训练后 PPL 和蒸馏 loss。PPL 降低仍不等于 护理答案正确。

--eval-data 是独立于蒸馏语料的能力集。提供后,SaddleLLM 会在蒸馏完成后用完全相同的 设置顺序评估教师和学生,并把 baseline.json、candidate.json、comparison.json 和 report.md 写入 输出目录/evaluation/。--eval-task auto 会识别常见 question/answer 选择题或 instruction/output completion 数据;也可以显式指定 multiple-choice 或 completion。选择题报告准确率增减、能力保留率和配对 McNemar p; completion 报告参考答案 PPL 的前后变化和确定性生成样例。

低显存数据蒸馏可以把教师放在另一个 SaddleLLM 服务中;--concurrency 并发请求教师:

# 1. 生成候选答案;不会自动训练
saddlellm distill --mode data `
  --student Qwen/Qwen3-0.6B `
  --teacher qwen3-4b-teacher `
  --teacher-url http://127.0.0.1:8002 `
  --data data\nursing_prompts.jsonl `
  --domain nursing --concurrency 4 `
  --output-dir outputs\nursing-distill-data

# 2. 护理教师纠正 JSONL 后,才训练学生
saddlellm distill --mode data `
  --student Qwen/Qwen3-0.6B `
  --teacher-data data\nursing_teacher_reviewed.jsonl `
  --eval-data data\nursing_validation.jsonl `
  --method lora --epochs 1 `
  --output-dir outputs\nursing-distilled-sft

--teacher-url 接受服务根地址、/v1 地址或完整 /v1/chat/completions 地址。密钥只通过 --api-key-env ENV_NAME 传入。在线结果的 metadata.review_status 为 pending;在医疗场景,较大的模型也可能给出危险错误,因此 SaddleLLM 不把回答长度启发式当作临床正确性,也不在同一命令中直接启动 SFT。 此时即使传入 --eval-data 也只会记录为“等待审核后训练”;没有训练后的学生就不存在可比 评估。审核数据进入第二条命令后,才会自动比较原始 student 与蒸馏后的 adapter/完整模型。

创建持久化 CPU INT8 模型:

saddlellm quantize outputs\nursing-release outputs\nursing-int8 --local-files-only
saddlellm serve outputs\nursing-int8 --device cpu --open

saddlellm lightweight ... 与 quantize 完全相同。当前不把 GPTQ/AWQ、静态 QAT 或 “一键剪枝+量化”伪装成稳定命令;这些格式只有在完成可重载、可生成和真实基准验证后才会 进入 CLI。每次量化、剪枝或蒸馏后,仍应单独运行 evaluate 和 compare。

复杂、多阶段或需要续训的任务继续使用 YAML/JSON 配置:

一个可直接运行的 SFT 配置:

project: saddlellm
experiment: my-sft
stages: [sft]

model:
  name_or_path: Qwen/Qwen2.5-0.5B-Instruct
  tokenizer: Qwen/Qwen2.5-0.5B-Instruct
  backend: hf

sft:
  enabled: true
  data_path: data/sft.jsonl
  use_lora: true
  use_qlora: false
  epochs: 1
  learning_rate: 0.0002
  per_device_batch_size: 1
  gradient_accumulation_steps: 4
  max_seq_length: 1024
  warmup_steps: 0
  save_steps: 50

training:
  max_steps: 100

distributed:
  strategy: single
  num_gpus: 1
  bf16: false
  fp16: false

logging:
  output_dir: outputs/my-sft
  backend: local

顶层字段的职责:

字段 作用
project 项目名,用于记录
experiment 本次实验名
stages 要执行的阶段;必须是非空、无重复的字符串列表
model 模型路径、tokenizer 和后端
data 预训练使用的数据源和清洗参数
training 全局步数、预训练超参数、checkpoint、恢复和 dry-run 设置
distributed 单机或分布式策略、GPU 数和精度
logging 总输出目录和日志后端
pipeline 可选的依赖关系和阶段级恢复设置
与阶段同名的块 该阶段自己的数据、方法和超参数

推荐显式写出阶段开关:

stages: [sft, preference, eval]

sft:
  enabled: true

preference:
  enabled: true
  method: dpo

eval:
  enabled: true

stages 决定系统是否调度该阶段;对带 enabled 开关的阶段,该开关决定收到调度后是否工作。最不容易出错的写法是:把 sft、preference、eval 等列入 stages 时,其配置块同时写 enabled: true。

文本后训练方法:

方式 配置
全参数训练 use_lora: false,use_qlora: false
LoRA use_lora: true,use_qlora: false
QLoRA use_lora: true,use_qlora: true

training.max_steps 的含义:

  • 大于 0:最多运行指定步数。
  • 等于 -1:由阶段自己的 epochs 决定训练长度。
  • 等于 0 或小于 -1:配置无效。

对于 train 使用的训练配置,相对路径按运行命令时的当前目录解释。为了避免路径错误,建议在仓库根目录运行仓库内的示例,或在 quickstart 目录内运行生成的配置。

2.4 推荐的使用顺序

第一步:检查环境

saddle-llm doctor

检查 Python、PyTorch、Transformers、Datasets、Accelerate、PEFT、TRL、CUDA、GPU、内存和磁盘。

主要返回:

{
  "ready": true,
  "python_version": "...",
  "cuda_available": true,
  "gpu_count": 1,
  "gpu_memory_gb": 20.0,
  "packages": {},
  "issues": [],
  "recommendations": []
}

ready: false 时看 issues。没有 GPU 会被标记为问题,但极小的 CPU 测试仍可能运行。

第二步:检查数据

SFT:

saddle-llm inspect-data data/sft.jsonl --task sft

DPO/ORPO:

saddle-llm inspect-data data/preference.jsonl --task dpo

KTO:

saddle-llm inspect-data data/kto.jsonl --task kto

返回 ready、样本数、字段格式、文本长度、重复样本和阻断问题。SFT 数据还会报告 dominant_prompt_prefix_ratio 与 dominant_completion_shape_ratio:当同一种提示前缀或回答形态占比过高时, 命令会警告模板过拟合风险,并建议加入自然问法、改写问法和无包装问法。同一个原始样本的不同问法必须放在 同一数据切分中,避免变体泄漏到 validation/test。重复的 system message 不计作用户提示模板。数据不合格时退出码为 1; 模板集中属于质量警告,不会替用户武断阻断训练。

第三步:检查配置

saddle-llm validate-config config.yaml

返回:

{
  "valid": true,
  "stages": ["sft"],
  "issues": [],
  "warnings": [],
  "data_inspections": {},
  "training_estimates": {},
  "normalized_config": {},
  "config_path": "config.yaml"
}

它会检查阶段名、必填数据、模型后端、训练步数、精度冲突、分布式能力、动作空间和发布门禁等。只检查结构、不打开本地数据时使用:

saddle-llm validate-config config.yaml --skip-data-inspection

第四步:查看执行顺序

saddle-llm train config.yaml --dry-run

返回 stages、pipeline_plan、distributed 和数据源数量。这个参数不会加载模型或训练,只展示调度顺序;完整数据检查仍应使用 validate-config。

第五步:正式训练

saddle-llm train config.yaml

成功时返回:

{
  "ok": true,
  "command": "train",
  "config": "config.yaml",
  "output_dir": "outputs/my-sft",
  "next": {
    "dashboard": "saddlellm dashboard \"outputs/my-sft\" --open"
  },
  "results": {
    "sft": {
      "status": "completed",
      "model_path": "outputs/my-sft/sft_checkpoints"
    }
  }
}

失败时返回 ok: false、异常类型和错误信息,并以退出码 1 结束。需要完整 Python 堆栈时:

saddle-llm train config.yaml --debug

2.5 基础命令

命令 做什么 最小用法 主要结果
quickstart 创建入门训练目录 saddle-llm quickstart .\demo config.yaml、样例数据、下一步命令
doctor 检查环境和依赖 saddle-llm doctor ready、硬件、依赖、问题和建议
inspect-data 检查 SFT/偏好/RL 数据 saddle-llm inspect-data data.jsonl --task sft 数据质量报告
inspect-vla 检查 VLA 轨迹、图像和动作维度 saddle-llm inspect-vla robot.jsonl --image-root images VLA 数据报告
validate-config 静态校验训练配置 saddle-llm validate-config config.yaml valid、问题、警告和训练量估算
evaluate 评测基座、完整模型或LoRA saddlellm evaluate MODEL eval.jsonl 选择题准确率或completion PPL、真实生成和Markdown报告
compare 配对比较validation/test并执行门禁 saddlellm compare --base-validation base.json --candidate-validation tuned.json 提升、McNemar检验、泄漏检查和晋级决策
train 执行配置或直接SFT saddlellm train sft --model MODEL --data DATA checkpoint、指标和输出路径
dashboard(webui) 查看训练进度、曲线、阶段和日志 saddlellm dashboard outputs/my-run --open 本地 Web 仪表盘,默认端口 7860
plan 生成启动命令,不训练 saddle-llm plan config.yaml launch_plan.json 和 launch.ps1
preflight 针对一个后训练任务检查数据并生成计划 saddle-llm preflight data.jsonl --stage sft preflight_plan.json、config.json、阻断项和估算
plugins 列出内置和已安装的阶段 saddle-llm plugins 阶段名称、来源和加载状态
smoke-test 用本地 tiny 模型检查训练主链 saddle-llm smoke-test --in-process SFT、VLA、DPO、ORPO、KTO 等测试结果
import-data 导入数据 manifest saddle-llm import-data dataset_info.json 保存位置、数据摘要和导入数量

plan 根据 distributed.strategy 生成启动文件。它不执行训练:

saddle-llm plan configs/sft_lora.yaml
.\configs\launch.ps1

preflight 一次只检查一个后训练任务,所以参数使用单数 --stage。真正的训练配置仍使用复数 stages:

saddle-llm preflight data/posttrain_sft_example.jsonl --stage sft --root-dir .\llm_factory

2.6 媒体和生成命令

这些命令用于单独执行某个工具;它们的参数文件只是该命令的输入,不是 train 使用的训练配置。

命令 做什么 最小用法 主要结果
media-codecs 查看已注册的图像、音频或视频编码器 saddle-llm media-codecs --modality image Codec 名称、模态和能力
build-media-cache 把原始媒体清单编码成可恢复分片 saddle-llm build-media-cache configs/media_cache_image.yaml cache manifest、分片路径和样本统计

同样的媒体处理也可以放入主训练配置:

stages: [media_cache, image_generation]

完整示例见 raw_image_to_training.yaml。

2.7 世界模型和眼动控制命令

命令 做什么 最小用法 主要结果
world-model-backends 查看 RSSM 后端 saddle-llm world-model-backends 可用后端及能力
train-world-model 单独训练世界模型 saddle-llm train-world-model configs/world_model.yaml --dry-run 推断出的维度、训练计划;去掉 --dry-run 后返回 checkpoint 信息
infer-world-model 从 checkpoint 做 rollout 或动作规划 saddle-llm infer-world-model CHECKPOINT request.json 预测轨迹、奖励或候选动作
build-eye-control-data 生成安全过滤后的双轴眼动轨迹 saddle-llm build-eye-control-data --episodes 128 JSONL 数据路径和生成统计
simulate-eye-control 在软件仿真器评估 PID 或 RSSM+CEM saddle-llm simulate-eye-control --config configs/prosthetic_eye_runtime.yaml 跟踪误差、安全事件和控制统计

世界模型也能作为主训练阶段运行:

saddle-llm train configs/world_model_stage.yaml

世界模型训练后立即做眼动控制评估:

saddle-llm train configs/prosthetic_eye_control.yaml

2.8 空间智能和 WorldAgent 命令

命令 做什么 最小用法 主要结果
build-spatial-world-data 从俯视图生成空间世界模型轨迹 saddle-llm build-spatial-world-data map.png --output data/spatial.jsonl 轨迹数据和生成统计
evaluate-spatial-world-model 评估多步占用、运动和碰撞预测 saddle-llm evaluate-spatial-world-model CHECKPOINT data.jsonl 分项评测指标
plan-spatial-route 从地图提取占用网格并规划 Top-K 路线 saddle-llm plan-spatial-route map.png --start 10,20 --goal 300,200 路线 JSON、HTML 和 PNG
spatial-studio 启动可视化空间工作台 saddle-llm spatial-studio 前台 HTTP 服务,默认端口 7865
world-agent-run 一次执行分析、规划和仿真 saddle-llm world-agent-run map.png --start 10,20 --goal 300,200 状态、候选路线、仿真和产物路径
world-agent-api 启动无界面的 WorldAgent API saddle-llm world-agent-api 前台 HTTP 服务,默认端口 7866

dashboard、webui、spatial-studio、world-agent-api 和 serve 是持续运行的服务命令,不会像普通命令一样立即返回。按 Ctrl+C 正常停止。

2.9 评测、发布和服务命令

以下示例统一使用 saddlellm。安装包仍保留 saddle-llm 这个可执行文件名;旧子命令 evaluate-model、compare-evaluations、export-model、serve-model 也继续作为兼容别名。推荐新脚本使用短命令 evaluate、compare、export、serve。

命令 做什么 最小用法 主要结果
report 汇总一个训练输出目录 saddlellm report outputs/my-run 预训练/运行报告
evaluate 对本地JSONL/JSON评测模型、adapter或服务 saddlellm evaluate MODEL eval.jsonl --local-files-only 选择题准确率、completion PPL或声明式rubric、逐题JSON和Markdown报告
compare 成对比较基座/候选的validation和封存test saddlellm compare --base-validation base.json --candidate-validation tuned.json McNemar显著性、提升、checkpoint选择和发布决策
export 把 checkpoint 或 adapter 打包成可验证发布目录 saddlellm export CHECKPOINT outputs/release 模型文件、manifest、可选权重哈希和门禁信息
dashboard(webui) 查看训练目录 saddlellm dashboard outputs/my-run --open 进度、指标、loss 曲线、阶段、产物和日志
serve 启动 OpenAI 兼容 API 和内置对话页 saddlellm serve outputs/release --open /、/v1/models、流式 /v1/chat/completions、/v1/completions

多选题评测文件默认使用 instruction、question、answer、id 字段;可用 --prompt-field、--question-field、--answer-field、--id-field 修改。answer 必须是 --choices 中的一个标签。评测基座:

saddlellm evaluate Qwen/Qwen3-0.6B data/validation.jsonl `
  --local-files-only --group-field medical_discipline `
  --batch-size 32 --max-length 384 `
  --output outputs/base_validation.json `
  --markdown-output outputs/base_validation.md

若要发现模型是否只记住一种提问模板,可以用领域项目维护的普通 JSON 模板文件,一次展开 同一批题目的多种问法:

{
  "variants": [
    {"name": "standard", "template": "{instruction}"},
    {"name": "natural", "template": "请回答下题,只给选项字母。\n{question}\n{options}"},
    {"name": "bare", "template": "{question}\n{options}"}
  ]
}
saddlellm evaluate Qwen/Qwen3-0.6B data/validation.jsonl `
  --prompt-variants configs/prompt_variants.json `
  --local-files-only --batch-size 32 `
  --output outputs/base_robustness.json `
  --markdown-output outputs/base_robustness.md

模板中的占位符来自每条原始记录;缺字段、重复题号或同题答案不一致会直接报错。报告包含 每种问法准确率、最差问法准确率、预测翻转率,以及“所有问法都答对”的病例比例。也可以先 在数据中自行展开变体,再用 --case-field 和 --variant-field 指定同题编号与变体名。 这些机制完全与领域无关;护理、法律等具体模板应放在各自项目中,不写进 SaddleLLM 核心。

评测LoRA并运行全部真实生成:

saddlellm evaluate Qwen/Qwen3-0.6B data/test.jsonl `
  --adapter outputs/run/sft_checkpoints/checkpoint-100 `
  --local-files-only --generation-all `
  --output outputs/candidate_test.json `
  --markdown-output outputs/candidate_test.md

completion-only PPL只计算参考回答token,不把问题token混入loss;数据默认使用 instruction 和 output 字段:

saddlellm evaluate Qwen/Qwen3-0.6B data/sft_validation.jsonl `
  --task completion --local-files-only `
  --generation-samples 3 --max-length 512 `
  --output outputs/completion_eval.json `
  --markdown-output outputs/completion_eval.md

PPL只能在相同模型tokenizer、chat template、数据和截断规则下比较;PPL更低不等于事实更正确。自由回答仍要结合生成回归和领域专家审核。指定 --generation-samples 或 --generation-indices 后,Markdown会同时展开问题、确定性生成和可折叠参考答案,便于直接审查实际回答。

开放回答可使用领域项目维护的声明式 rubric。核心只提供 contains_any、contains_all、not_contains_any、regex、not_regex 五种通用检查; 护理规则和阈值不能写进 SaddleLLM 核心:

{"id":"case-1","instruction":"...","rubric":{"pass_threshold":0.8,"checks":[{"id":"escalate","type":"contains_any","patterns":["通知医生","启动急救"],"weight":2,"critical":true,"dimension":"escalation"}]}}

直接加载本地模型评估:

saddlellm evaluate MODEL rubric.jsonl --task rubric --local-files-only `
  --output outputs/rubric.json --markdown-output outputs/rubric.md

也可复用已经由 saddlellm serve 启动的 OpenAI 兼容服务,不重复占显存:

saddlellm evaluate served-model rubric.jsonl --task rubric `
  --endpoint http://127.0.0.1:8000 --max-new-tokens 128 `
  --output outputs/rubric.json --markdown-output outputs/rubric.md

rubric 会生成每条回答并报告通过率、加权分、分维度结果和关键失败数;空回答永不通过。 这些确定性规则只是可审计的工程筛查,不是专家评分、事实正确性或临床安全证明。比较 rubric 时可用 compare --max-critical-failures 0 阻止平均分上升但关键项仍失败的候选模型。

正式发布时同时比较 validation 和封存 test。若提供数据 manifest,指定的重叠统计必须全部为0:

saddlellm compare `
  --base-validation outputs/base_validation.json `
  --candidate-validation outputs/candidate_validation.json `
  --base-test outputs/base_test.json `
  --candidate-test outputs/candidate_test.json `
  --manifest data/dataset_manifest.json `
  --overlap-key exact_question_overlap_after_exclusion `
  --min-gain-pp 5 --max-p 0.05 `
  --output outputs/release_gate.json `
  --markdown-output outputs/release_gate.md

evaluate 会同时保留每题预测与归一化标签概率;加 --generation-all 后还保存贪心生成文本和解析结果。标签概率与开放生成可能不同,因此二者不能互相替代。compare 使用同题配对变化和精确McNemar检验,不把训练loss或PPL当作实际正确率。

只传 validation 时,compare 可用于选择 checkpoint:达到阈值会写 decision=validation_passed、selection_eligible=true,但始终保持 accepted=false。只有同时提供成对的封存 test,且 validation/test 都通过阈值时,才会写 decision=promoted、accepted=true。因此 validation-only 报告不能绕过 export --require-gate;test 一旦解封也不得继续参与调参。

checkpoint、release 与部署

  • 推荐让 train 配置只包含训练阶段(例如 stages: [sft])。评估、比较、导出和部署随后通过独立命令串联,不需要把它们塞进一次训练调用。
  • checkpoint 是训练过程存档,适合继续训练和快速调试。
  • release 是通过 export 整理出的交付目录,适合复制到服务器、比赛提交和长期保存。
  • export 会整理模型权重、配置和 tokenizer。LoRA adapter 默认与基座模型合并,并生成 release_manifest.json;它不会执行模型评估。
  • serve 只加载指定模型并启动服务,不执行评估,也不要求评估通过。

训练完成后可以直接启动 checkpoint,不必先导出:

saddlellm serve E:\DEV\medModel\outputs\my-run\sft_checkpoints\checkpoint-100 `
  --local-files-only --device cuda --open

显存优先时可做运行时量化(不会另存量化权重):

saddlellm serve E:\DEV\medModel\outputs\my-run\sft_checkpoints\checkpoint-100 `
  --local-files-only --device cuda --dtype bfloat16 --quantization 8bit --open

--quantization 可选 none、8bit、4bit。量化依赖 bitsandbytes,请安装 .[serve,qlora];量化可能改变任务答案,上线前必须重新评估该精度下的模型效果。

确认版本准备交付时,再导出成独立 release 目录:

saddlellm export `
  E:\DEV\medModel\outputs\my-run\sft_checkpoints\checkpoint-100 `
  E:\DEV\medModel\outputs\my-release `
  --local-files-only

然后部署 release 模型:

saddlellm serve E:\DEV\medModel\outputs\my-release `
  --local-files-only --device cuda `
  --host 127.0.0.1 --port 8000 --open

如果团队需要在 CI 或正式发布流水线中自动阻止未达标版本,可以选择在导出阶段检查已有评估报告。普通调试、导出和部署不需要这个参数:

saddlellm export CHECKPOINT outputs/release `
  --gate-result outputs/run/release_gate.json --require-gate

推荐的完整命令链如下;每一步都可以独立重跑,前一步的文件路径作为后一步输入:

saddlellm train config.yaml
  └─ checkpoint
      └─ saddlellm evaluate ...
          └─ evaluation.json
              └─ saddlellm compare ...
                  └─ comparison.json
                      └─ saddlellm export checkpoint release
                          └─ saddlellm serve release --open

浏览器对话和 OpenAI 兼容 API 共用同一个模型实例,不会重复占用显存。聊天接口支持 SSE 流式输出;默认关闭模型的显式思考输出,并把默认生成长度限制为 256 token。只有确实需要时才加 --enable-thinking。模型评估由 evaluate/compare 单独完成,部署命令只加载指定模型;若目录包含 release manifest,健康接口会显示其中的门禁信息但不重新评估。这个内置服务用于单机验证和低并发应用;100 并发要接入支持连续批处理的生产推理后端并实测容量。

如果需要 Bearer Token,不要把密钥直接写进命令:

$env:SADDLE_API_KEY = "your-secret"
saddlellm serve outputs/release --api-key-env SADDLE_API_KEY

训练可视化、推理页面、API 示例和生产边界见 WebUI 与快速部署。

2.10 Python 调用

直接运行配置:

from saddlellm.training.TrainingOrchestrator import TrainingOrchestrator

runner = TrainingOrchestrator.from_yaml("config.yaml")
results = runner.run()
print(results)

从字典运行:

from saddlellm.training.TrainingOrchestrator import TrainingOrchestrator

config = {
    "stages": ["sft"],
    "model": {
        "backend": "hf",
        "name_or_path": "Qwen/Qwen2.5-0.5B-Instruct",
    },
    "sft": {
        "enabled": True,
        "data_path": "data/sft.jsonl",
        "use_lora": True,
        "use_qlora": False,
    },
    "training": {"max_steps": 10},
    "distributed": {"strategy": "single", "bf16": False},
    "logging": {"output_dir": "outputs/python-run"},
}

results = TrainingOrchestrator.from_dict(config).run()

只做静态校验:

import yaml
from saddlellm.training.TrainingConfigValidator import TrainingConfigValidator

with open("config.yaml", encoding="utf-8") as handle:
    config = yaml.safe_load(handle)

report = TrainingConfigValidator.validate(config)
print(report.to_dict())

2.11 返回状态和输出目录

阶段结果中的常见 status:

状态 含义
completed、trained 已实际执行成功
planned 只生成计划,没有训练
planned_no_data 缺少数据,只保存计划
planned_unsupported 已识别,但真实执行尚未接入
skipped 阶段被关闭
rejected 评测门禁未通过
blocked 因上游条件不满足而阻止执行
failed 执行失败

典型输出目录:

outputs/my-run/
├─ plans/
│  ├─ sft_plan.json
│  ├─ preference_plan.json
│  └─ export_plan.json
├─ sft_checkpoints/
├─ preference_checkpoints/
├─ final_model/
├─ release/
├─ pipeline_state.json
├─ release_gate.json
├─ summary.json
└─ training_summary.json

不同 stages 只生成与自己有关的目录。summary.json 和 training_summary.json 记录执行顺序、耗时、各阶段结果和产物。

3. 原理、代码逻辑和训练过程

3.1 一条命令进入系统后发生什么

执行:

saddle-llm train config.yaml

内部顺序:

cli.py
  1. 读取 YAML/JSON
  2. 检查顶层 stages 是非空、无重复的字符串列表
        ↓
TrainingOrchestrator._parse_config()
  3. 把 model、training、distributed 和各阶段参数解析成配置对象
        ↓
StageRegistry
  4. 确认每个阶段有对应实现,并读取它的能力限制
        ↓
PipelinePlan
  5. 确定执行顺序和依赖关系
        ↓
TrainingOrchestrator._validate_config()
  6. 在模型加载前检查数据、后端、精度、分布式和阶段组合
        ↓
TrainingOrchestrator.run()
  7. 逐个执行阶段,保存状态和产物
        ↓
summary.json + 命令行 JSON

CLI 只负责读取参数和展示结果。真正的训练入口位于 TrainingOrchestrator,具体数学计算由各 Trainer 完成。

3.2 阶段如何排序

默认按 stages 的书写顺序执行:

stages: [sft, preference, eval, export]

顺序就是:

sft → preference → eval → export

存在独立分支时可以显式声明依赖:

stages: [sft, world_model, preference, eval, export]

pipeline:
  dependencies:
    sft: []
    world_model: []
    preference: [sft]
    eval: [preference, world_model]
    export: [eval]

此时 sft 与 world_model 没有相互依赖;eval 必须等待两条分支完成。系统会检查不存在的依赖、重复阶段和依赖环。

简单任务不需要写 pipeline.dependencies。

3.3 阶段之间怎样交接

文本模型主链:

model.name_or_path
        │
        ├───────────────┐
        ▼               │
     pretrain           │
        │ model_path    │
        ▼               │
       sft ◄────────────┘
        │ model_path
        ▼
 preference / rlhf
        │ model_path
        ▼
       eval
        │ metrics + release_gate
        ▼
      export

后一个阶段优先使用前一个阶段返回的 model_path。没有上游模型时,才使用 model.name_or_path。

数据产物也可以交接:

mopd 产生 on-policy JSONL → sft.data_path 为空时由 SFT 使用
media_cache 产生编码分片 → image/music/video generation 使用
world_model 产生 checkpoint → eye_control 使用

每个阶段返回一个普通字典。系统把结果保存在阶段结果表中,同时登记可追踪产物。

3.4 预训练逻辑

pretrain 有三种启动方式:

方式 关键配置 含义
从零训练 pretrain_mode: scratch 从内置模型规格或 model.blueprint 创建新模型
继续预训练 pretrain_mode: continue + model.name_or_path 载入已有权重,以新的优化任务继续训练
精确恢复 training.resume_from_checkpoint 在支持的 Trainer 中恢复优化器、调度器和训练步数

实际过程:

  1. 解析模型规格或 blueprint。
  2. 创建新模型,或加载已有模型/checkpoint。
  3. 加载已有 tokenizer,或使用上游 tokenizer 阶段的结果。
  4. 从 data.sources 收集数据。
  5. 清洗、去重和质量过滤后先划分训练/验证集,避免同一数据同时参与训练和验证。
  6. tokenize 时保留长文档全部 token,在每个文档末尾补 EOS,再做 sequence packing。
  7. 使用只屏蔽真实 padding、不会误屏蔽 EOS 的 causal-LM collator。
  8. 创建 Hugging Face Trainer 或原生 SaddleTrainer,执行 causal language modeling。
  9. 开训前检查tokenizer词表、模型embedding、EOS/PAD契约,以及过滤/packing后训练集和验证集是否为空。
  10. 按验证 loss 选择最佳 checkpoint,并记录验证 PPL、实际全局 batch、token 吞吐、各清洗阶段样本数和最终序列数。
  11. 保存 final_model、tokenizer 和 Trainer state。

最小结构:

stages: [pretrain]
pretrain_mode: scratch

model:
  backend: saddle
  config: qwen-tiny-160m
  tokenizer: Qwen/Qwen2.5-0.5B

data:
  sources:
    - type: local
      path: data/pretrain.jsonl
      text_column: text
      streaming: false
  append_eos: true
  validation_split: 0.01

training:
  max_steps: 1000
  per_device_batch_size: 2
  global_batch_size: 32
  learning_rate: 0.0003
  min_lr: 0.00003
  eval_every_steps: 100
  save_every_steps: 500
  load_best_model_at_end: true

distributed:
  strategy: single

logging:
  output_dir: outputs/pretrain

没有显式设置 distributed.gradient_accumulation_steps 时,系统按 global_batch_size / (per_device_batch_size × num_gpus × num_nodes) 自动推导;不能整除或显式值 与全局 batch 不一致时会在模型加载前报错。默认 cosine 会实际使用 min_lr,映射到带最小学习率 的 cosine scheduler。validation_split: 0 可以关闭内部验证,但将无法得到验证 PPL和最佳 checkpoint。

完整原生模型结构示例见 modular_llm.yaml。

3.4.1 用简单配置表达网络结构

网络结构采用“预设继承 + 可选覆盖”,不要求每次重复几十个字段:

pretrain_mode: scratch
model:
  backend: saddle
  config: qwen-300m              # 预设提供层数、宽度、词表等完整默认值
  tokenizer: Qwen/Qwen2.5-0.5B
  blueprint:
    name: nursing-dense-300m
    max_position_embeddings: 8192
    attention:
      kind: gqa
      backend: sdpa
      num_heads: 16
      num_kv_heads: 4
      rope_theta: 1000000
    ffn:
      kind: swiglu
      intermediate_size: 2816
    residual:
      topology: serial
      initialization: depth_scaled

配置分三档:

场景 写法 结构来源
继续预训练 pretrain_mode: continue + model.name_or_path 完全继承 checkpoint,不允许伪造新层数
常规从零预训练 pretrain_mode: scratch + model.config 使用已登记且测试过的完整结构预设
架构研究 预设再加 model.blueprint,或提供自包含 blueprint 覆盖注意力、FFN、上下文、残差、目标和分层结构

blueprint.layers还能用repeat表达不同层段,例如前16层dense、后4层MoE;没有该字段时所有层采用同一默认结构。预检会验证隐藏维度能否整除头数、GQA头数关系、MoE专家数量、RoPE和上下文参数等。训练保存时同时写出model_blueprint.json与saddle_config.json,因此 checkpoint 自带真实网络结构。

开训前查看展开后的参数量、激活参数量、KV cache估算、结构轴和风险:

saddlellm validate-config configs/nursing_pretrain_scratch.yaml --skip-data-inspection

输出中的architecture_analysis就是最终生效的结构,不是仅供展示的注释。完整可运行模板见nursing_pretrain_scratch.yaml。实际护理参评项目若没有数十亿级以上高质量token和相应算力,应优先对成熟Base模型做继续预训练;从零预训练的小模型主要用于验证自主架构和训练能力。

3.5 SFT 逻辑

sft 用“输入指令 → 目标回答”训练模型遵循任务要求。

支持的数据形式包括:

{"instruction":"概括下面内容","input":"待处理文本","output":"目标回答"}

以及 messages:

{"messages":[{"role":"user","content":"问题"},{"role":"assistant","content":"目标回答"}]}

多轮 messages 中的每一个非空 assistant 回答都会形成一个 completion-only 训练样本; 该回答之前的完整对话作为上下文但不计算监督损失。因此一条 JSONL 对话可能对应多个 train_samples,不会再只训练最后一个回答。若回答在 max_seq_length 截断后完全消失, 该轮会被丢弃,不会错误地拿 prompt token 充当答案监督。

执行过程:

  1. 从上游 pretrain 或 model.name_or_path 找到模型。
  2. 检查数据字段、空文本、重复样本和长度。
  3. 生成 plans/sft_plan.json。
  4. 根据 use_lora/use_qlora 选择全参数、LoRA 或 QLoRA。
  5. 优先读取独立 validation_data_path;未提供时才按 validation_split 划分。
  6. HF 后端调用 PeftSFTTrainer;Saddle 后端调用原生 SFT。
  7. 有验证集时按最低 eval_loss 恢复最佳 checkpoint,再保存根 sft_checkpoints 并返回新的 model_path。

示例见 sft_lora.yaml。

3.6 偏好训练逻辑

preference 用于让模型在多个回答之间学习偏好。

方法 数据 作用
DPO prompt/chosen/rejected 直接提高 chosen 相对 rejected 的概率
ORPO prompt/chosen/rejected 将监督目标和偏好比率目标结合
KTO prompt/completion/label 用可取/不可取标签学习偏好;实际 batch 必须大于 1

**KTO 是什么:**KTO 全称 Kahneman-Tversky Optimization,是一种偏好优化方法。 它不要求像 DPO 那样为同一个问题同时准备 chosen 和 rejected 成对回答;每条样本只需提供 一个回答,并用 label: true/false 标明“可取/不可取”。因此,当护理教师只能逐条审核回答、 而难以为每题编写严格配对答案时,KTO 更容易整理数据。KTO 的主要作用是调整回答偏好、 规范性和安全性,不负责向模型灌入大量新知识;新知识应先通过继续预训练或 SFT 学习。

--stage sft,kto 的逗号表示 SaddleLLM 严格按 SFT → KTO 执行,并把 SFT 输出交给 KTO; 这只是执行顺序,不代表 KTO 永远必须接在 SFT 后。若基座模型已经具备所需知识和指令能力, 也可以单独运行 --stage kto。

DPO/ORPO 数据:

{"prompt":"怎样排错?","chosen":"先看日志并构造最小复现。","rejected":"直接忽略错误。"}

KTO 数据:

{"prompt":"怎样排错?","completion":"先看日志。","label":true}

执行过程:

  1. 取得执行顺序中最近完成的前置语言模型;例如 sft → ppo → kto 中 KTO 必须消费 PPO 输出。
  2. 按选定方法检查数据。
  3. 写入 plans/preference_plan.json。
  4. 调用对应 DPO、ORPO 或 KTO Trainer。
  5. 保存 preference_checkpoints,供评测或导出使用。

示例见 posttrain.yaml 和 dpo_qlora.yaml。

rlhf 阶段当前可实际执行的稳定路径也是 DPO。PPO 需要 reward model、value model、在线 rollout 和经过安全验证的奖励契约,目前实际训练会在所有阶段开始前明确失败;需要稳定离线偏好训练时直接使用 DPO、ORPO 或 KTO。

3.7 MOPD 蒸馏逻辑

mopd 的目标是先让当前学生模型生成回答,再让一个或多个教师评价或重写,最后形成新的 SFT 数据。

prompts
  → 学生生成候选
  → 教师评分/聚合
  → mopd_on_policy.jsonl
  → 可选后续 sft

mopd.dry_run: true 只写计划。设置为 false 且提供 prompts、教师和可用模型时才收集数据。 远程教师可设置 teacher_concurrency 并发数。requires_review: true 时,每条记录会标为 review_status: pending,且后续 SFT 不能直接消费该 MOPD 产物;必须由领域专家修订后通过 sft.data_path 显式传回。直接命令 saddlellm distill --mode data 默认采用这个安全语义。

示例见 mopd_sft.yaml。

3.8 多模态和 VLA 逻辑

vla_sft 处理“图像/指令/机器人动作”轨迹:

  1. 创建并校验动作空间,包括维度、连续/离散类型、范围、夹爪和控制频率。
  2. 检查图像路径、动作维度和 episode step 连续性。
  3. 规范化为训练 JSONL。
  4. 总是保存动作空间和训练计划。
  5. 只有 vla.train: true 时才调用 VLATrainer 做行为克隆训练。

示例见 vla_sft.yaml。该示例默认 train: false,因此只做规范化和计划。

mllm_sft 和 vision_alignment 当前只完成图文数据规范化与计划保存,不应把返回的 planned 当作模型已经训练。

3.9 图像、音乐和视频生成逻辑

生成训练分为两步:

原始媒体 + 文本
       ↓
media_cache:Codec 编码媒体,文本编码器生成 condition
       ↓
NPZ/分片缓存
       ↓
image_generation / music_generation / video_generation
       ↓
模型 checkpoint
  • 图像:读取 latents[N,C,H,W] 和 conditions[N,D]。
  • 音乐:读取 codes[N,Q,T]、conditions[N,D] 和可选 mask。
  • 视频:读取 video_latents[N,C,T,H,W] 和 conditions[N,D]。

训练前会从缓存推断模型维度,并拒绝与手工配置不一致的通道数、码本数或条件维度。

示例:

3.10 世界模型和控制逻辑

world_model 从离线轨迹学习:

当前观测 + 动作
      ↓
隐状态更新
      ↓
下一观测、奖励和 continuation 预测

数据通常包含 observation、action、reward 和 done。rssm 使用连续随机状态;categorical_rssm 使用离散类别状态。训练结果可用于 rollout、候选动作评分和空间控制。

eye_control 不直接驱动硬件。它在软件 plant 中应用角度、速度、加速度、电流和温度限制,然后比较 PID 或 RSSM+CEM 控制效果。真实硬件仍需要单独实现安全驱动适配器。

示例:

3.11 评测和导出逻辑

eval 的模型选择顺序:

rlhf 输出
  → preference 输出
  → sft 输出
  → pretrain 输出
  → model.name_or_path

评测成功后可生成 release_gate.json。例如要求 perplexity 不超过阈值:

eval:
  enabled: true
  tasks: [perplexity]
  gate:
    enabled: true
    rules:
      perplexity:
        max: 30.0
    fail_on_rejection: true

export 使用最新上游模型。如果配置 require_gate: true,没有已接受的门禁结果就拒绝导出。

完整闭环示例见 posttrain_release.yaml。

3.12 Batch、步数和显存逻辑

有效 batch:

effective_batch
= per_device_batch_size
× gradient_accumulation_steps
× num_gpus

显存主要受模型参数量、序列长度、每卡 batch、优化器状态、是否全参数训练和精度影响。常用选择:

  • 显存充足:全参数或 LoRA。
  • 显存较小且有兼容 CUDA/bitsandbytes:QLoRA。
  • OOM:先降低 per_device_batch_size 和序列长度,再提高梯度累积保持有效 batch。
  • CPU:只适合 tiny 模型、数据检查和调度测试。

bf16 与 fp16 不能同时启用。

3.13 恢复、失败和状态逻辑

阶段级恢复:

pipeline:
  resume: true
  rerun: []
  state_path: pipeline_state.json

系统只会恢复配置指纹和依赖图一致、且上次已完成的阶段。pipeline.rerun 指定某个阶段重跑时,它的下游阶段也会失效并重新执行。

Trainer checkpoint 恢复使用:

training:
  resume_from_checkpoint: outputs/run/checkpoint-1000

这与阶段级恢复不同:前者恢复单个 Trainer 内部状态,后者决定整个阶段是否跳过。 直接单阶段命令也可使用 --resume-from-checkpoint [PATH];省略 PATH 时从该阶段输出目录 选择最大的 checkpoint-*。精确恢复允许增大 max_steps,但必须保持有效训练 batch 不变, 否则数据游标已经不再等价,系统会在训练前拒绝。

任何阶段抛出异常时:

  1. 记录 failed_stage 和错误。
  2. 更新 pipeline_state.json。
  3. 尽可能写出 summary.json。
  4. 停止后续阶段。
  5. CLI 返回非零退出码,不把失败包装成成功。

3.14 当前文本模型训练验收范围

2026-09-13 在 Windows、单张 RTX 4090 Laptop GPU、项目锁定的 Transformers/TRL/PEFT 环境中,以下路径均由真实 Trainer 执行,不是只做参数解析:

路径 证据目录 关键结果
Saddle 原生蓝图从零预训练 + 精确续训 E:/DEV/medModel/artifacts/training_acceptance_scratch_native_v1 自定义2层GQA、75,520参数,checkpoint-1恢复到step 2,验证PPL 7.9969
HF模型继续预训练 + 精确续训 E:/DEV/medModel/artifacts/training_acceptance_pretrain_resume_v1 checkpoint-2恢复到step 3,验证PPL 12.7266
全参数SFT + 精确续训 E:/DEV/medModel/artifacts/training_acceptance_full_sft_v1 恢复到step 3,最终eval loss 3.1267
QLoRA SFT E:/DEV/medModel/artifacts/training_acceptance_qlora_eval_v2 4bit加载、BF16计算、训练/最终验证/保存均完成
LoRA SFT→KTO串联 E:/DEV/medModel/artifacts/training_acceptance_sft_kto_chain_v1 两阶段各1 step,continued_adapter=true
DPO + 验证 + 精确续训 E:/DEV/medModel/artifacts/training_acceptance_dpo_eval_v1 恢复到step 3,DPO验证指标已写入summary
ORPO / KTO E:/DEV/medModel/artifacts/training_acceptance_orpo_eval_v2、training_acceptance_kto_eval_v2 真实训练、最终验证和adapter保存完成
多轮SFT + 独立验证 + all-linear E:/DEV/medModel/artifacts/training_acceptance_quality_core_v1 HF QLoRA/DPO/ORPO/KTO与Saddle原生SFT/DPO均真实完成;2条源记录展开为3个回答样本;各路径选择最佳checkpoint
安装版核心SFT复验 E:/DEV/medModel/artifacts/training_acceptance_installed_quality_core_v1 从源码目录外调用saddlellm.exe;3个训练样本、2个独立验证样本、all-linear目标和最佳checkpoint均进入summary
logits蒸馏 + 独立评估 E:/DEV/medModel/artifacts/direct_distill_with_eval_smoke 训练成功,但独立completion PPL退化,报告如实标记degraded
PPO E:/DEV/medModel/artifacts/training_acceptance_ppo_boundary_v1 仅支持dry-run;真实执行在任何阶段开始前明确失败

这些 tiny smoke 证明数据读取、前向/反向、优化器、验证、checkpoint、续训和报告链路可用, 不证明长时训练、多机多卡或模型业务效果。DDP/FSDP/DeepSpeed仍需在目标集群做容量验收;PPO 尚未实现;护理checkpoint的临床安全与比赛效果必须由独立题集和教师审核另行证明。

该验收对应wheel: E:/DEV/medModel/artifacts/wheel_build_quality_core_v1/saddlellm-2.35-py3-none-any.whl 。交付时用 Get-FileHash -Algorithm SHA256 核对项目SOP中记录的最终哈希。 源码全量回归为391 passed、20条第三方warning、0 failed;安装版saddlellm.exe又完成了一次 真实LoRA SFT、独立验证和最佳checkpoint恢复。

3.15 从哪里继续阅读

开发验证:

python -m compileall -q saddlellm tests
python tools/generate_function_reference.py --check
python -m pytest -q

Metadata

Release files for saddlellm 2.36

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for saddlellm 2.36
File Size Uploaded Provenance Actions
saddlellm-2.36.tar.gz 869.1 kB Without provenance Details for saddlellm-2.36.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for saddlellm 2.36
File Interpreter ABI Platform Actions
saddlellm-2.36-py3-none-any.whl Python 3 none any Details for saddlellm-2.36-py3-none-any.whl

Total release size: 1.7 MB

Release files / saddlellm-2.36.tar.gz

Download URL saddlellm-2.36.tar.gz
Size 869.1 kB
Tags Source
SHA-256 checksum
How to use checksums
a8365741bfeb0529c01048f732302d2ea2f879da2c0007ca51800956dea533c5
BLAKE2b-256 checksum
How to use checksums
0098f0565e35d36cdca3f69321cdf76731888cf1026b956053ccd251b0f435c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.0rc2

Release files / saddlellm-2.36-py3-none-any.whl

Download URL saddlellm-2.36-py3-none-any.whl
Size 831.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
47396a4adc8948a75ba502b8fd1ce551b8c66b23fd26dd7698a7821d11e7db7e
BLAKE2b-256 checksum
How to use checksums
c945d2b40f2fd53d1f5c597a3eb29510daa92c5d84e1ed86f64e874ceb2b9392
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.0rc2

Security for saddlellm 2.36

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page