English | 中文
Hy3 preview 提供了模型训练相关流程,您可以在此章节对训练数据格式进行处理以供模型训练使用。
Hy3 preview 同时支持慢思考与快思考两种模式,模型的默认输出是慢思考模式,若想让模型进行快思考,可通过 reasoning_effort 参数控制(可选值:high、low、no_think)。
训练数据按照以下形式处理为 messages 格式,训练和推理的默认 system prompt 为空,可以根据自己的需求进行设定。
# Fast thinking pattern (no_think)
{"reasoning_effort": "no_think", "messages": [{"content": "你是一个有用的人工智能助手。\n现在的时间是2026-01-01 13:26:12 周四", "role": "system"}, {"content": "1+1=?", "role": "user"}, {"role": "assistant", "content": "1+1=2"}]}
# Slow thinking pattern (high)
{"reasoning_effort": "high", "messages": [{"content": "你是一个有用的人工智能助手。\n现在的时间是2026-01-01 13:26:12 周四", "role": "system"}, {"content": "1+1=?", "role": "user"}, {"role": "assistant", "content": "1+1=2", "reasoning_content": "1+1=2"}]}
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("./models", use_fast=False, trust_remote_code=True)
ids = tokenizer.apply_chat_template(messages, is_training=True)Hy3 preview 的原始 checkpoint 采用每个 expert 独立存储的格式,在训练前需要转换为 expert 融合后的 HuggingFace 标准格式(将同一层的多个 expert 权重融合为 3D 张量,并统一 key 命名),用于提高加载和训练的速率。我们提供了转换脚本 convert_ckpt_to_outer.py 和校验脚本 check_converted.py,位于 train/tools 目录下。
python convert_ckpt_to_outer.py \
--input_dir <原始checkpoint目录> \
--output_dir <输出目录> \
--workers 8参数说明:
--input_dir:原始 checkpoint 目录路径(必选)--output_dir:转换后的 checkpoint 输出目录路径(必选)--workers:并行转换的进程数,默认为 8(可选)转换脚本会执行以下步骤:
model.safetensors.index.json,检测跨 shard 的 expert 分组config.json、tokenizer 等其他文件model.safetensors.index.json转换完成后,建议使用校验脚本验证转换结果的完整性:
python check_converted.py <转换后的checkpoint目录> --spot-check 3参数说明:
--spot-check:随机抽检的 shard 文件数量,会加载 tensor 并检查 shape、dtype、NaN/Inf 等,默认为 3(可选)校验脚本会检查以下内容:
config.json 的完整性model.safetensors.index.json 中所有预期 key 是否齐全(包括常规层和 MTP 层)您可以参照快速开始文档中的内容进行快速上手。
经过测试,不开 make_moe_param_leaf_module 以及 zero3+offload,max_seq_length 为 4096,使用LORA,全量微调最少需要单机 8 卡(显存至少80G)。
如果不使用LORA,最少需要4机32卡(显存至少80G)。
参考:HuggingFace Transformers Trainer
在train目录下,执行:
pip install -r requirements.txt
bash train.sh如果要用多台机器启动训练,请按照以下步骤执行,并保证多台机器在一个集群内。
以下操作以两个机器为例,两台机器的 ip 分别以${ip1}和${ip2}标识,以下操作均在 docker container 内执行。
首先,配置多机container免密,在每台机器上执行。
ssh-keygen # 生成id_rsa和id_rsa.pub,用于免密登录
ssh-keygen -t rsa -A # 生成/etc/ssh/ssh_host_rsa_key和ssh_host_ecdsa_key, 用于后面启动ssh listen
/usr/sbin/sshd -p 36005 -o ListenAddress=0.0.0.0 # 启动 SSH 监听
echo "Port 36005" > ~/.ssh/config # ssh 连接端口修改为 36005
passwd root # 需要配置root密码,否则监测平台会报警注意:这里的36005是一个示例端口,可以选用任意端口,但需要保证使用的端口开放且不被其他的进程占用。
接下来,在每台机器的 container 内,执行:
cat ~/.ssh/id_rsa.pub将输出的 ssh 公钥复制并粘贴到~/.ssh/authorized_keys文件中,每行一个公钥,每台机器上都要做这个操作。最终每台机器上的~/.ssh/authorized_keys文件内容应当是一致的,并且包含了所有机器的公钥。
需要注意,多节点训练时,每个节点上执行的代码都得一致,建议挂载一个共享的网络盘,如果无法挂载共享网盘,则需要手动将数据集、脚本、代码复制在多台机器的相同目录下。
在以上准备步骤准备好了之后,以及确认依赖已经安装完成(如未安装,请执行pip install -r requirements.txt安装),就可以在train.sh中的开头增加以下配置:
export HOST_GPU_NUM=8
# IP list, comma separated. e.g. "192.168.1.1,192.168.1.2" or single node "192.168.1.1"
IP_LIST=${IP_LIST:-"127.0.0.1"}注意:如果IP_LIST环境变量未设置,则将IP_LIST替换为IP列表!格式为:
如果只有一个IP:
IP_LIST=${ip_1}
如果有多个IP:
IP_LIST=${ip_1},${ip_2}
请将${ip_1}和${ip_2}替换为真实的IP地址。
然后,在${ip1}的机器上,在train/目录下,执行bash train.sh即可,注意第一次启动时可能会看见以下的输出:
The authenticity of host '[ip]:36005 ([ip]:36005)' can't be established.
ECDSA key fingerprint is xxxxxx.
ECDSA key fingerprint is MD5:xxxxxx.
Are you sure you want to continue connecting (yes/no)?此时输入yes即可继续。
脚本中的关键参数如下:
--deepspeed: 此参数应当指向一个 deepspeed 的配置文件,train文件夹下提供了三种 DeepSpeed 的默认配置文件:ds_zero2_no_offload.json, ds_zero3_no_offload.json, ds_zero3_offload.json,这三个配置文件所需显存依次减少--model_name_or_path: 要加载的 Hy3 preview 的 HF 预训练模型权重,否则无法加载--tokenizer_name_or_path: tokenizer 文件夹路径, 否则无法加载--train_data_file: 训练文件路径,应该为一个 jsonl 文件--output_dir: 输出文件夹,log、tensorboard 和权重都会存储在这个路径下--per_device_train_batch_size: 每张卡上的 batch size--gradient_accumulation_steps: 梯度累计次数,per_device_train_batch_size * gradient_accumulation_steps * dp_size为 global_batch_size--max_steps: 训练的总步数--save_steps: 每多少个 step 存储一个 checkpoint--use_lora: 是否用 lora 训练,同时接收--lora_rank,--lora_alpha和--lora_dropout参数。lora 默认应用于 "q_proj", "k_proj", "v_proj", "o_proj" 四个参数,如果需要改变的话在代码中修改即可。注意:使用 lora 训练时,只会保存 lora 的权重,而不会保存 base 模型的权重,如果需要合并 lora 权重,看下面的“Lora 权重合并”一节--make_moe_param_leaf_module:当用 zero3 以及 MoE 训练时,将 MoE 模块视作一个 leaf module,即它的参数不进行 zero3 切分,这个选项预计会显著增加显存占用--gradient_checkpointing:开启梯度重计算--train_attention_params_only: 是否只训练 attention 参数--learning_rate: 训练时的最大学习率--min_lr: 训练时的最小学习率--use_flash_attn: 开启 flash-attention 进行训练加速注意:
--resume_from_checkpoint为之前训练保存的 ckpt 路径,不要指定--model_name_or_path,这样只会加载权重,而不会加载训练状态--model_name_or_path 有效时,所有模型相关的参数都会被忽略可以尝试修改 ds config,去掉这几个参数的 auto 属性,改小试试看:
stage3_param_persistence_thresholdstage3_prefetch_bucket_sizestage3_max_reuse_distance保存下来的 lora 权重没法在训练运行时合并到 zero3 模型中,因为 zero3 开启时模型权重会切分到各 dp rank 上。因此如果想把 lora 权重合并到 base 模型上,可以通过离线的方式合并后得到权重文件。执行merge_lora_weight.sh即可完成 lora 权重和 base 模型权重的合并,其中的参数有:
--base_model_path:base 模型的权重目录--adapter_model_path:lora 权重目录--output_path:合并后的权重保存目录--save_dtype: 以什么数据格式存储合并后的权重,可选值:fp16,bf16,fp32如果对 LLaMA-Factory 较为熟悉,可使用LLaMA-Factory进行微调。脚本、代码以及配置文件都归档在./train/llama_factory_support目录下。如果没有特别说明,接下来我们提到的文件都是该目录下的文件。
可以通过下载源码 https://github.com/hiyouga/LLaMA-Factory/tree/main ,根据网站的指引进行安装。
我们提供了 llama-factory 的训练示例配置文件 hy_v3_lora_sft.yaml和hy_v3_full_sft.yaml文件,分别对应LORA训练和非LORA训练。
脚本中的关键参数如下:
模型相关:
model_name_or_path: Hy3 preview HF 格式预训练模型权重路径trust_remote_code: 是否信任远程代码, Hy3 preview 需要设置为 true训练方法:
stage: 训练阶段, 当前为 sft(监督微调)finetuning_type: 微调类型, 可选 full(全量微调) 或 lora(LoRA 微调)deepspeed: DeepSpeed 配置文件路径, 全量微调推荐 ds_zero3_offload_hy.json, LoRA 微调推荐 ds_zero2_offload_lora.jsonLoRA 参数(仅 LoRA 微调时生效):
lora_rank: LoRA 秩, 默认 64lora_alpha: LoRA alpha 系数, 默认 128lora_dropout: LoRA dropout 比率, 默认 0.05lora_target: LoRA 应用的目标模块, 默认为 q_proj,k_proj,v_proj,o_proj数据集:
dataset_dir: 数据集目录路径dataset: 数据集名称, 需要在 dataset_dir 下的 dataset_info.json 中注册template: 对话模板, Hy3 preview 使用 hy_v3cutoff_len: 最大序列长度, 超出部分会被截断; 全量微调可设为 262144(262K), LoRA 微调建议设为 8192 以节省显存max_samples: 每个数据集最多使用的样本数overwrite_cache: 是否覆盖已缓存的预处理数据集输出:
output_dir: 输出目录, 日志、TensorBoard 和权重都会存储在此路径下logging_steps: 每多少步记录一次日志save_steps: 每多少步保存一次 checkpointplot_loss: 是否绘制训练 loss 曲线overwrite_output_dir: 是否覆盖已有的输出目录save_only_model: 是否只保存模型权重(不保存优化器状态等)report_to: 日志上报工具, 可选 none, wandb, tensorboard, swanlab, mlflow训练超参数:
per_device_train_batch_size: 每张卡上的 batch sizegradient_accumulation_steps: 梯度累积步数, per_device_train_batch_size * gradient_accumulation_steps * dp_size 为 global batch sizelearning_rate: 最大学习率, 全量微调推荐 1.0e-5, LoRA 微调推荐 2.0e-4num_train_epochs: 训练轮数lr_scheduler_type: 学习率调度器类型, 推荐使用 cosine_with_min_lrlr_scheduler_kwargs.min_lr_rate: 最小学习率与最大学习率的比值, 例如 0.1 表示最小学习率为最大学习率的 10%warmup_ratio: 预热阶段占总训练步数的比例bf16: 是否使用 BFloat16 混合精度训练gradient_checkpointing: 是否开启梯度重计算以节省显存ddp_timeout: 分布式训练超时时间(毫秒)flash_attn: 注意力实现方式, 推荐 fa2(FlashAttention-2), 也可选 sdpa; 使用 fa2 需要安装 flash-attn 包resume_from_checkpoint: 从指定 checkpoint 路径恢复训练, 设为 null 表示从头开始训练请先按照前面章节 配置机器间免密 ssh 登录 配置多机免密登录。
修改train_lf.sh中开头的以下配置:
export HOST_GPU_NUM=8
# IP list, comma separated. e.g. "192.168.1.1,192.168.1.2" or single node "192.168.1.1"
export IP_LIST=${IP_LIST:-"127.0.0.1"}注意:如果IP_LIST环境变量未设置,则将IP_LIST替换为IP列表!格式为:
如果只有一个IP:
IP_LIST=${ip_1}
如果有多个IP:
IP_LIST=${ip_1},${ip_2}
请将${ip_1}和${ip_2}替换为真实的IP地址。
然后,在每一台机器上,在train/llama_factory_support/目录下执行bash train_lf.sh。