❤️ 如果你也关注大模型与 AI 的发展现状,且对大模型应用开发非常感兴趣,我会快速跟你分享最新的感兴趣的 AI 应用和热点信息,也会不定期分享自己的想法和开源实例,欢迎关注我哦!
🥦 微信公众号|搜一搜:蚝油菜花 🥦
🚀 快速阅读
- Hunyuan-Large 是腾讯推出的大规模混合专家(MoE)模型,具有 3890 亿总参数和 520 亿激活参数。
- 该模型支持高达 256K 的文本序列输入,显著提升长上下文任务的处理能力。
- 在多个基准测试中,Hunyuan-Large 表现出色,超越了 Llama3 和 Mixtral 等主流开源模型。
正文(附运行示例)
Hunyuan-Large 是什么
Hunyuan-Large 是腾讯推出的大规模混合专家(MoE)模型,具有 3890 亿总参数量和 520 亿激活参数量,是目前业界参数规模最大的开源 MoE 模型。基于 Transformer 架构,支持高达 256K 的文本序列输入,显著提升长文本任务的处理能力。Hunyuan-Large 在长上下文处理、中英文自然语言处理、代码生成、数学运算等 9 大能力维度上表现出色,超越了 Llama3 和 Mixtral 等主流开源模型。
Hunyuan-Large 的主要功能
- 高质量文本创作:Hunyuan-Large 能生成高质量的文章、写作、润色、总结和创意文本,适用于多种写作场景。
- 知识问答:模型具备广泛的知识理解能力,能回答用户的各种知识性问题,提供准确的信息和解释。
- 多轮对话:Hunyuan-Large 支持流畅的多轮对话,能与用户进行自然的交流,理解上下文给出恰当的回答。
- 数学逻辑和代码创作:模型在数学逻辑和编程代码的生成和理解方面表现出色,能协助用户解决数学问题和编写代码。
Hunyuan-Large 的技术原理
- 长上下文处理能力:预训练模型支持高达 256K 的文本序列输入,显著提升处理长上下文任务的能力。
- 高质量合成数据:通过合成数据增强训练,Hunyuan-Large 能学习到更丰富的表示,更好地泛化到未见数据。
- KV 缓存压缩:采用分组查询注意力(GQA)和跨层注意力(CLA)策略,减少了 KV 缓存的内存占用和计算开销,提高了推理吞吐量。
- 专家特定学习率缩放:为不同专家设置不同的学习率,确保每个子模型都能有效地从数据中学习并为整体性能做出贡献。
- 广泛的基准测试:在多种语言和任务上进行广泛实验,验证 Hunyuan-Large 的实际应用效果和安全性。
- MoE 扩展法则:研究 MoE 模型的扩展法则,指导模型设计和优化。
- 多语言支持:支持中文和英文,能处理多语言任务。
如何运行 Hunyuan-Large
模型训练
为了简化部署过程,HunyuanLLM 提供了预构建的 Docker 镜像:hunyuaninfer/hunyuan-large。
硬件需求
经过在 H20 上测试,不开 make_moe_param_leaf_module
以及 zero3+offload
,max_seq_length
为 2048,全量微调最少需要 32 卡,LoRA 微调最少需要 8 卡。
训练性能
最低配置(8 卡 LoRA 精调)测试下,per_device_train_batch_size
为 1,gradient_accumulation_steps
为 1,大约 35s 一个 iteration。
启动方式
参考:HuggingFace Transformers Trainer
单机启动训练
在 train
目录下,执行:
pip install -r requirements.txt
bash train.sh
多机启动训练
如果要用多台机器启动训练,请按照以下步骤执行,并保证多台机器在一个集群内。
配置机器间免密 ssh 登录
以下操作以两个机器为例,两台机器的 ip 分别以 ${ip1}
和 ${ip2}
标识,以下操作均在 Docker 容器内执行。
首先,配置多机容器免密,在每台机器上执行。
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 # 启动 Listen
echo "Port 36005" > ~/.ssh/config # ssh 连接端口修改为 36005
passwd root # 需要配置 root 密码,否则监测平台会报警
注意:这里的 36005
是一个示例端口,可以选用任意端口,但需要保证使用的端口开放且不被其他进程占用。
接下来,在每台机器的容器内,执行:
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
export LOCAL_IP=${ip1}
# 多节点机器 ip,逗号隔开
export NODE_IP_LIST="${ip1}:8,${ip2}:8"
# 机器节点个数
export NODES=2
export NODE_NUM=$((${NODES} * ${HOST_GPU_NUM}))
注意:将以上的 ${ip1}
和 ${ip2}
替换为真实的 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
: 要加载的 HF 预训练模型权重,确保这个路径下包含了modeling_hunyuan.py
和configuration_hunyuan.py
文件,否则无法加载--tokenizer_name_or_path
: tokenizer 文件夹路径,确保这个路径下包含了tokenization_hy.py
文件,否则无法加载--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 进行训练加速
注意:
- 如果想从一个中途保存的 ckpt 继续训练,而不是加载一个预训练的权重,直接指定
--resume_from_checkpoint
为之前训练保存的 ckpt 路径,不要指定--model_name_or_path
,这样只会加载权重,而不会加载训练状态 - 从 ckpt 继续训练时,loss 可能会有微小的偏差,这是由一些非确定性算法带来的随机性,是正常现象。参考:[HuggingFace Transformers Trainer Randomness]
- 当
--model_name_or_path
有效时,所有模型相关的参数都会被忽略 - 一个 batch 内的样本会通过 padding 对齐 batch 内最长的样本,而每条样本的长度最长为 max_seq_length,超出的部分会被裁剪
- 如果报出 bias 权重没有 load 的 warning,忽略即可,Hunyuan-Large 中不会用到 bias
显存不足怎么办?
参考:DeepSpeed Configuration
可以尝试修改 ds config,去掉这几个参数的 auto 属性,改小试试看:
stage3_param_persistence_threshold
stage3_prefetch_bucket_size
stage3_max_reuse_distance
stage3_max_reuse_distance
Lora 模型合并
保存下来的 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
推理和部署
HunyuanLLM 采用 vLLM 部署。为了简化部署过程,HunyuanLLM 提供了预构建的 Docker 镜像,详见【使用 vLLM 推理】章节。
使用 vLLM 推理
Docker:
为了简化部署过程,HunyuanLLM 提供了预构建的 Docker 镜像:
hunyuaninfer/hunyuan-large。您只需要下载模型文件并用下面代码启动 Docker 即可开始推理模型。
docker run --name hunyuanLLM_infer -itd --privileged --user root --net=host --ipc=host --gpus=8 hunyuaninfer/hunyuan-large:infer-open-source
注: Docker 容器权限管理。以上代码采用特权模式(–privileged)启动 Docker 容器会赋予容器较高的权限,增加数据泄露和集群安全风险。建议在非必要情况下避免使用特权模式,以降低安全威胁。对于必须使用特权模式的场景,应进行严格的安全评估,并实施相应的安全监控、加固措施。
配置机器间免密 ssh 登录
以下操作以两个机器为例,两台机器的 ip 分别以 ${ip1}
和 ${ip2}
标识,以下操作均在 Docker 容器内执行。
首先在两台机器上面运行:passwd
设置密码,例如:Tmp123,./
将 inference/login_ssh.py
拷贝到容器中,执行如下命令,注意 IP 和密码填入正确值。
python3 login_ssh.py --ips ${ip1},${ip2} --port 36000 --password=Tmp123,./
注意 📢:在启动前请务必通过 VLLM 的多机验证脚本: https://docs.vllm.ai/en/latest/getting_started/debugging.html
BF16 部署
BF16 需要 16 卡 H800、H20 部署。验证多机通信无误后,按如下步骤执行:
运行命令前请先设置如下环境变量:
${LOCAL_IP}:当前机器 bond1 对应 IP
${MODEL_PATH}:Hunyuan LLM 模型路径
Step1:Ray 启动
Ray 是一个并行和分布式 Python 的开源库,本章节我们采用 Ray 来实现多机通信。
Ray 组件配置加固:Ray 组件默认配置中服务端口(如 6379、8265)未启用身份验证机制,存在未授权访问和命令执行的风险。建议在部署 Ray 组件时,仅在受信任的内部网络环境中进行,或确保对这些端口实施严格的访问控制列表(ACL)策略,禁止非授权网络访问。
首先我们在各个节点上启动 ray(放在后台启动或者保持终端运行状态):
主节点上:
export VLLM_HOST_IP=${LOCAL_IP}
export NCCL_SOCKET_IFNAME=bond1
export GLOO_SOCKET_IFNAME=bond1
ray start --block --head --node-ip-address=${LOCAL_IP} --port=6379
所有子节点:
注意:{主节点 $LOCAL_IP} 需填入主节点的 ${LOCAL_IP}
export VLLM_HOST_IP=${LOCAL_IP}
export NCCL_SOCKET_IFNAME=bond1
export GLOO_SOCKET_IFNAME=bond1
ray start --block --address={主节点 $LOCAL_IP}:6379 --node-ip-address=${LOCAL_IP}
如果启动 ray 失败,执行 ray stop
后再次执行上述命令。
Step2:执行推理
方式 1:命令行推理
下面我们展示一个代码片段,采用 vLLM
快速请求 chat model:
注: vLLM 组件远程代码执行防护。下列代码中 vLLM 组件的 trust_remote_code
配置项若被启用,将允许加载并执行来自远程模型仓库的代码,这可能导致恶意代码的执行。除非业务需求明确要求,否则建议该配置项处于禁用状态,以降低潜在的安全威胁。
import os
from vllm import LLM, SamplingParamsmodel_path = os.environ.get('MODEL_PATH')llm = LLM(model=model_path,tokenizer=model_path,trust_remote_code=True,max_model_len=10240,dtype='bfloat16',tensor_parallel_size=16,pipeline_parallel_size=1,disable_log_stats=False,gpu_memory_utilization=0.98,disable_custom_all_reduce=True,enforce_eager=True,max_num_seqs=8,use_v2_block_manager=True,quantization=None)prompts = ["海水为什么是咸的"]sampling_params = SamplingParams(temperature=0.7, top_p=0.6, max_tokens=200, top_k=20, repetition_penalty=1.05)outputs = llm.generate(prompts, sampling_params)# Print the outputs.
for output in outputs:prompt = output.promptgenerated_text = output.outputs[0].textprint(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")
方式 2:服务化推理
下面我们展示使用 vLLM
服务化的方式部署模型并请求
在主节点上运行:
export VLLM_HOST_IP=${LOCAL_IP}
export NCCL_SOCKET_IFNAME=bond1
export GLOO_SOCKET_IFNAME=bond1
接着我们启动服务,运行 :
cd inference
sh run_server.sh
Tips:故障处理,如果遇到
ray, exceptions.RaySystemError: System error: No module named 'transformers_modules' traceback: Traceback (most recent call last):
ModuleNotFoundError: No module named 'transformers modules'
将主节点上的 ~/.cache/huggingface/modules/
拷贝到所有子节点相应路径。
运行 run_server.sh
成功后, 运行请求脚本:
sh openapi.sh
注意修改 openapi.sh
中的 ${LOCAL_IP}
和 ${MODEL_PATH}
为服务对应值。
量化模型部署
本部分介绍采用 vLLM 部署量化后模型的流程。
镜像:部署镜像同 BF16。
Int8 量化模型部署
部署 Int8-weight-only 版本 Hunyuan-L 模型只需设置 run_server_int8.sh
中的环境变量:
${MODEL_PATH} : BF16 模型路径
${LOCAL_IP} : 当前机器 bond1 对应 IP
接着我们启动 Int8 服务。运行:
sh run_server_int8.sh
运行 run_server_int8.sh
成功后, 运行请求脚本:
sh openapi.sh
FP8 量化模型部署
部署 W8A8C8-FP8 版本 Hunyuan-L 模型只需设置 run_server_int8.sh
中的环境变量:
${MODEL_PATH} : FP8 模型路径
${LOCAL_IP} : 当前机器 bond1 对应 IP
接着我们启动 FP8 服务。运行:
sh run_server_fp8.sh
运行 run_server_fp8.sh
成功后, 运行请求脚本:
sh openapi.sh
FP8 BENCHMARK
本部分介绍 Hunyuan Large Instruct FP8 量化模型的效果评估。
Dataset | BF16 | W8A8C8-FP8 |
---|---|---|
ARC-C | 94.6 | 94.2 |
C-Eval | 88.6 | 89.2 |
CMMLU | 90.4 | 89.8 |
MMLU | 89.9 | 88.9 |
性能评估
本部分介绍采用 vLLM 部署各个模型(原始模型和量化模型)的效率测试结果,包括不同 Batchsize 下的推理速度(tokens/s)。
Inference Framework | Model | Number of GPUs (H20) | input_length | batch=1 | batch=4 |
---|---|---|---|---|---|
vLLM | Hunyuan-Large | 16 | 2048 | 20.2 | 75.5 |
vLLM | Hunyuan-Large (int8 weight only) | 8 | 2048 | 19.3 | 73.6 |
vLLM | Hunyuan-Large (W8A8C8-FP8) | 8 | 2048 | 19.8 | 74.9 |
资源
- 项目官网:https://llm.hunyuan.tencent.com/
- GitHub 仓库:https://github.com/Tencent/Tencent-Hunyuan-Large
- Hugging Face 模型库:https://huggingface.co/tencent/Tencent-Hunyuan-Large
- arXiv 技术论文:https://arxiv.org/pdf/2411.02265
- hunyuaninfer/hunyuan-large:https://hub.docker.com/repository/docker/hunyuaninfer/hunyuan-large/general
- HuggingFace Transformers Trainer:https://huggingface.co/docs/transformers/v4.19.2/en/main_classes/trainer
- DeepSpeed Configuration:https://www.deepspeed.ai/docs/config-json/
❤️ 如果你也关注大模型与 AI 的发展现状,且对大模型应用开发非常感兴趣,我会快速跟你分享最新的感兴趣的 AI 应用和热点信息,也会不定期分享自己的想法和开源实例,欢迎关注我哦!
🥦 微信公众号|搜一搜:蚝油菜花 🥦