- 人工智能
- 大模型
- 预训练
- 微调
- LoRA
- RLHF
- 强化学习
- 分布式训练
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
本文面向希望在燧原(Enflame)S60 推理加速卡上运行 Llama2-13B 大语言模型的开发者,完整介绍基于 PaddleNLP 的 GCU 推理环境搭建、wikitext-103 困惑度(ppl)评估流程,以及use_fused_rope、fuse_attention_qkv、fuse_attention_ffn等融合算子配置的底层实现原理。阅读本文后,你将能够在一台插有燧原 S60 的机器上完成从驱动安装、镜像启动、PaddleCustomDevice 编译到 Llama2-13B 推理评估的全过程,并理解 GCU 算子融合调用的具体路径。
背景:GCU 推理入口与 GPU 的基本统一
燧原 S60 是面向数据中心大规模部署的新一代人工智能推理加速卡,覆盖大语言模型、搜索/推荐及传统模型等需求,具备模型覆盖面广、易用性强、易迁移易部署等特点,可广泛应用于图像及文本生成、搜索与推荐、文本/图像/语音识别等主流推理场景。
PaddleNLP 在燧原 S60 上对 Llama2-13B 模型进行了深度适配与优化,实现了 GCU 推理入口与 GPU 的基本统一:仅需修改device参数即可完成推理任务的迁移。这一设计在评估脚本的入参设计中可以直接印证——slm/examples/benchmark/wiki_lambada/eval.py 中--device参数的可选值为cpu / gpu / xpu / npu / gcu,GCU 与其他硬件后端共用同一套推理代码路径,只是底层算子分发到不同的自定义算子实现。
下文将以仓库中 docs/zh/llm/devices/gcu/llama/README.md 与配套脚本 llm/devices/gcu/llama/predict_llama_gcu.sh 为主线,完整复现 Llama2-13B 在燧原 S60 上的评估流程。
第 0 步:机器准备与加速卡验证
开始之前,需要准备一台插有燧原 S60 加速卡的机器,软件版本要求如下:
| 芯片类型 | 驱动版本 | TopsPlatform 版本 |
|---|---|---|
| 燧原 S60 | 1.0.5.1 | TopsPlatform_1.0.5.1-2c3111 |
验证机器是否插有燧原 S60 加速卡:在系统环境下执行以下命令,观察是否有输出:
lspci | grep S60 # 例如:lspci | grep S60 , 输出如下 01:00.0 Processing accelerators: Shanghai Enflame Technology Co. Ltd S60 [Enflame] (rev 01) 09:00.0 Processing accelerators: Shanghai Enflame Technology Co. Ltd S60 [Enflame] (rev 01)如果输出类似上面的设备行(每张 S60 卡对应一行),说明加速卡已被系统正确识别,可以继续后续环境准备。
第 1 步:环境准备(约 10~20 分钟)
1.1 初始化环境,安装驱动
联系燧原获取软件驱动包(邮箱:developer-enflame@enflame-tech.com)。假设安装包位于/home/paddle_user/deps/,名称为TopsPlatform.tar.gz,解压并安装驱动:
cd /home/paddle_user/deps/ && tar -zxf TopsPlatform.tar.gz cd TopsPlatform ./TopsPlatform_1.0.5.1-2c3111_deb_amd64.run --no-auto-load --driver -y1.2 拉取镜像
PaddleNLP 的 GCU 推理运行在 Paddle 官方开发镜像中。注意:此镜像仅为 Paddle 开发环境,不包含预编译的飞桨安装包与 TopsPlatform 安装包,相关组件需在容器内自行安装。
docker pull registry.baidubce.com/paddlepaddle/paddle:latest-dev1.3 启动容器
参考如下命令启动容器,将宿主机/home目录挂载进容器(便于访问 TopsPlatform 安装包等资源),并开启特权模式与宿主机网络/IPC:
docker run --name paddle-gcu-test -v /home:/home --network=host --ipc=host -it --privileged registry.baidubce.com/paddlepaddle/paddle:latest-dev /bin/bash1.4 安装编译套件
源码编译需要 CMake,在容器内安装 CMake 3.23.4:
cd /root wget https://github.com/Kitware/CMake/releases/download/v3.23.4/cmake-3.23.4-linux-x86_64.tar.gz tar -zxf ./cmake-3.23.4-linux-x86_64.tar.gz ln -sf /root/cmake-3.23.4-linux-x86_64/bin/cmake /usr/bin/cmake && ln -sf /root/cmake-3.23.4-linux-x86_64/bin/ctest /usr/bin/ctest1.5 安装燧原软件栈
在 Paddle 容器内安装燧原软件栈。编译与执行会依赖 sdk、runtime、eccl、aten、topstx(用于 profiler):
cd /home/paddle_user/deps/TopsPlatform ./TopsPlatform_1.0.5.1-2c3111_deb_amd64.run --no-auto-load -y dpkg -i topsfactor_*.deb tops-sdk_*.deb eccl_*.deb topsaten_*.deb1.6 安装 PaddlePaddle
PaddlePaddle(飞桨)提供运算基础能力,使用 CPU 版本即可(设备侧算子由 PaddleCustomDevice 提供):
python -m pip install paddlepaddle==3.0.0b0 -i https://www.paddlepaddle.org.cn/packages/stable/cpu/1.7 编译安装 PaddleCustomDevice
PaddleCustomDevice 是飞桨的自定义硬件接入实现,为 GCU 提供设备管理与算子实现。当前仍需源码编译,paddle-custom-gcu 预编译版本待发布:
# 下载源码 mkdir -p /home/paddle_user/workspace && cd /home/paddle_user/workspace git clone <PaddleCustomDevice 仓库地址> cd PaddleCustomDevice # 切换到 v3.0.0-beta1 版本 git checkout -b v3.0-beta v3.0.0-beta1 # 依赖的算子库 cp /home/paddle_user/deps/TopsPlatform/libtopsop.a ./backends/gcu/kernels/topsflame/ # 开始编译,依赖的第三方库会在首次编译时按需下载 cd backends/gcu/ && mkdir -p build && cd build export PADDLE_CUSTOM_PATH=`python -c "import re, paddle; print(re.compile('/__init__.py.*').sub('',paddle.__file__))"` cmake .. -DWITH_TESTING=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DPY_VERSION=3.9 make -j64 # 编译产物在 build/dist,使用 pip 安装 python -m pip install --force-reinstall -U dist/paddle_custom_gcu*.whl1.8 获取 PaddleNLP 仓库并安装
PaddleNLP 是基于飞桨的自然语言处理与 LLM 开发库,llama2-13B 模型实现包含其中。为了便于使用完整的模型与推理能力,需要 clone 整个仓库:
cd /home/paddle_user/workspace git clone https://gitcode.com/gh_mirrors/pa/PaddleNLP.git cd PaddleNLP # 切换到 v3.0.0-beta0 版本 git checkout -b v3.0-beta v3.0.0-beta0 # 安装依赖库 python -m pip install -r requirements.txt # 源码编译安装 paddlenlp v3.0.0-beta0 python setup.py bdist_wheel && python -m pip uninstall paddlenlp -y && python -m pip install dist/paddlenlp*第 2 步:数据准备(约 2~5 分钟)
使用训练好的模型在 wikitext-103 验证集上评估。进入 GCU 的 llama 示例目录并下载、解压数据集:
cd llm/devices/gcu/llama wget https://paddlenlp.bj.bcebos.com/data/benchmark/wikitext-103.tar.gz tar -zxf wikitext-103.tar.gz解压后得到wikitext-103/wiki.valid.tokens等文件,即后续评估脚本的输入。该数据集的通用准备方式也可以参考 slm/examples/benchmark/wiki_lambada/README.md(该目录还支持 wikitext-2 与 lambada 数据集)。
第 3 步:推理评估(约 15~30 分钟)
3.1 运行推理脚本
执行仓库自带的 GCU 推理脚本:
bash predict_llama_gcu.sh首次推理将自动下载权重和配置,存放于/root/.paddlenlp/models/__internal_testing__/sci-benchmark-llama-13b-5k/目录下。
3.2 推理脚本关键参数解析
查看 llm/devices/gcu/llama/predict_llama_gcu.sh,脚本核心内容可分为环境变量与评估命令两部分:
export PADDLE_RUN_ASYNC=true export FLAGS_use_stride_kernel=false export FLAGS_auto_growth_chunk_size_in_mb=512 export FLAGS_use_stream_safe_cuda_allocator=false export CUSTOM_DEVICE_BLACK_LIST="softmax_with_cross_entropy" export PYTHONPATH=../../../:$PYTHONPATH echo 'run llama wiki_text eval, log: wikitext_eval_gcu.log' python ../../../../slm/examples/benchmark/wiki_lambada/eval.py \ --model_name_or_path "__internal_testing__/sci-benchmark-llama-13b-5k" \ --device gcu \ --batch_size 4 \ --eval_path ./wikitext-103/wiki.valid.tokens \ --tensor_parallel_degree 1 \ --logging_steps 10 \ --use_flash_attention True \ --dtype float16 &> wikitext_eval_gcu.log &各环境变量的作用:
PADDLE_RUN_ASYNC=true:开启算子异步执行,利用流水线掩盖部分同步开销;FLAGS_use_stride_kernel=false:关闭 stride kernel,规避部分算子在不支持场景下的兼容性问题;FLAGS_auto_growth_chunk_size_in_mb=512:设置显存自动增长的最小分块为 512 MB,减少显存碎片与申请开销;FLAGS_use_stream_safe_cuda_allocator=false:关闭 stream-safe 分配器,适配 GCU 后端的显存管理;CUSTOM_DEVICE_BLACK_LIST="softmax_with_cross_entropy":将softmax_with_cross_entropy加入自定义设备算子黑名单,强制回退到 CPU/Paddle 基础实现,避免 GCU 自定义算子在此处的兼容问题。
评估命令核心参数:
--model_name_or_path "__internal_testing__/sci-benchmark-llama-13b-5k":使用 PaddleNLP 内部测试模型名,首次运行自动下载对应权重;--device gcu:指定运行设备为 GCU,这是与 GPU 推理的唯一核心差异;--batch_size 4:评估批大小;--eval_path ./wikitext-103/wiki.valid.tokens:评估数据文件;--tensor_parallel_degree 1:张量并行度,单卡场景为 1;--use_flash_attention True:开启 Flash Attention(对应下文配置中的use_flash_attention);--dtype float16:模型精度为 float16。
评估脚本的完整参数定义(含--seq_length、--overlapping_eval、--cloze_eval等)位于 slm/examples/benchmark/wiki_lambada/eval.py。例如--cloze_eval用于切换到 Lambada 完形填空式评估,此时输出的是准确率(number correct / avg accuracy)而非 ppl;--seq_length默认 512,控制滑窗评估的序列长度;--overlapping_eval默认 32,用于重叠滑窗评估。
3.3 推理配置文件调优:启用全部融合算子
推荐在首次下载权重文件后修改推理配置文件,以获取更大的性能提升。将/root/.paddlenlp/models/__internal_testing__/sci-benchmark-llama-13b-5k/config.json更改为以下内容:
{ "alibi": false, "architectures": [ "LlamaForCausalLM" ], "attention_probs_dropout_prob": 0.1, "bos_token_id": 1, "dtype": "float16", "eos_token_id": 2, "hidden_dropout_prob": 0.1, "hidden_size": 5120, "initializer_range": 0.002, "intermediate_size": 13824, "max_position_embeddings": 2048, "model_type": "llama", "num_attention_heads": 40, "num_hidden_layers": 40, "num_key_value_heads": 40, "pad_token_id": 0, "paddlenlp_version": null, "rms_norm_eps": 1e-06, "rope_scaling_factor": 1.0, "rope_scaling_type": null, "tie_word_embeddings": false, "use_recompute": false, "virtual_pp_degree": 1, "vocab_size": 32000, "use_fused_rope": true, "use_fused_rms_norm": true, "use_flash_attention": true, "fuse_attention_qkv": true, "fuse_attention_ffn": true }这份配置对应 Llama2-13B 的结构化参数:hidden_size=5120、intermediate_size=13824、40 层(num_hidden_layers)、40 个注意力头(num_attention_heads),且num_key_value_heads=40与注意力头数一致,即采用标准多头注意力(MHA)而非 GQA/MQA。对照 paddlenlp/transformers/llama/configuration.py 中LlamaConfig的默认值可以发现,fuse_attention_qkv、fuse_attention_ffn默认均为False,因此这份调优配置的关键在于将末尾五个融合相关字段置为true:
| 配置字段 | 作用 | 默认值 |
|---|---|---|
use_flash_attention | 使用 Flash Attention 加速注意力计算 | False(LlamaConfig 中未显式定义,模型按推理脚本传入) |
use_fused_rope | 使用融合版 RoPE 位置编码算子 | 需显式开启 |
use_fused_rms_norm | 使用融合版 RMSNorm 归一化算子 | 需显式开启 |
fuse_attention_qkv | 将 Q/K/V 三个投影合并为一次矩阵乘 | False |
fuse_attention_ffn | 将 FFN 的 gate/up 投影合并为一次矩阵乘 | False |
alibi | 是否启用 ALiBi 位置编码(llama 系列默认关闭) | False |
use_recompute | 是否开启重计算以节省显存(推理评估场景关闭) | False |
virtual_pp_degree | 虚拟流水线并行度(单卡推理为 1) | — |
3.4 结果解读:ppl 评估指标
成功运行后,可以在日志中查看到困惑度(ppl)评估结果,最终评估结果为ppl: 12.785:
[2024-08-16 01:55:24,753] [ INFO] - step 2000, batch: 2000, loss: 2.323283, speed: 1.40 step/s [2024-08-16 01:55:31,813] [ INFO] - step 2010, batch: 2010, loss: 2.341318, speed: 1.42 step/s [2024-08-16 01:55:38,859] [ INFO] - step 2020, batch: 2020, loss: 2.357684, speed: 1.42 step/s [2024-08-16 01:55:45,897] [ INFO] - step 2030, batch: 2030, loss: 2.371745, speed: 1.42 step/s [2024-08-16 01:55:52,942] [ INFO] - step 2040, batch: 2040, loss: 2.386801, speed: 1.42 step/s [2024-08-16 01:55:59,991] [ INFO] - step 2050, batch: 2050, loss: 2.399686, speed: 1.42 step/s [2024-08-16 01:56:07,037] [ INFO] - step 2060, batch: 2060, loss: 2.410638, speed: 1.42 step/s [2024-08-16 01:56:14,080] [ INFO] - step 2070, batch: 2070, loss: 2.421459, speed: 1.42 step/s [2024-08-16 01:56:21,141] [ INFO] - step 2080, batch: 2080, loss: 2.431433, speed: 1.42 step/s [2024-08-16 01:56:28,170] [ INFO] - step 2090, batch: 2090, loss: 2.443705, speed: 1.42 step/s [2024-08-16 01:56:35,238] [ INFO] - step 2100, batch: 2100, loss: 2.454847, speed: 1.41 step/s [2024-08-16 01:56:42,275] [ INFO] - step 2110, batch: 2110, loss: 2.464446, speed: 1.42 step/s [2024-08-16 01:56:49,323] [ INFO] - step 2120, batch: 2120, loss: 2.475107, speed: 1.42 step/s [2024-08-16 01:56:56,348] [ INFO] - step 2130, batch: 2130, loss: 2.487760, speed: 1.42 step/s [2024-08-16 01:57:03,372] [ INFO] - step 2140, batch: 2140, loss: 2.501706, speed: 1.42 step/s [2024-08-16 01:57:10,395] [ INFO] - step 2150, batch: 2150, loss: 2.513665, speed: 1.42 step/s [2024-08-16 01:57:17,411] [ INFO] - step 2160, batch: 2160, loss: 2.524555, speed: 1.43 step/s [2024-08-16 01:57:24,437] [ INFO] - step 2170, batch: 2170, loss: 2.536793, speed: 1.42 step/s [2024-08-16 01:57:31,461] [ INFO] - step 2180, batch: 2180, loss: 2.547897, speed: 1.42 step/s [2024-08-16 01:57:34,378] [ INFO] - validation results on ./wikitext-103/wiki.valid.tokens | avg loss: 2.5483E+00 | ppl: 1.2785E+01 | adjusted ppl: 2.6434E+01 | token ratio: 1.285056584007609 | 'Original Tokens: 279682, Detokenized tokens: 217642' 'Original Tokens: 279682, Detokenized tokens: 217642' I0816 01:57:34.386860 10925 runtime.cc:130] Backend GCU finalize device:0 I0816 01:57:34.386868 10925 runtime.cc:98] Backend GCU Finalizeppl 指标的计算方式:从 slm/examples/benchmark/wiki_lambada/eval.py 可以看到,评估过程将模型 logits 转成 float32 后计算cross_entropy,加权loss_mask得到平均损失(avg loss),再由ppl = exp(min(20, total_loss))得到困惑度。日志末尾的adjusted ppl是经过token ratio(token 化前后长度比)修正后的指标,token ratio: 1.285说明 wikitext-103 原始文本在 token 化后长度膨胀约 28.5%。日志中Backend GCU finalize字样来自飞桨 GCU 运行时(runtime.cc),确认整个评估过程运行在 GCU 后端上。
源码级原理:GCU 上的融合算子调用链
理解这份调优配置为什么能带来性能提升,关键在于观察 PaddleNLP 中 Llama 模型是如何根据这些配置分发算子的。以下调用链均可在当前仓库源码中逐一验证。
Flash Attention 的 GCU 分支
Llama 模型的注意力计算入口位于 paddlenlp/transformers/llama/modeling.py:当config.use_flash_attention为真时,直接进入fusion_ops.fusion_flash_attention。而 paddlenlp/transformers/llama/fusion_ops.py 中的实现按设备分流——当检测到get_env_device() == "gcu"时,会调用core.eager._run_custom_op("fused_sdp_flash_attention_gcu", ...),即 GCU 后端注册的融合 SDP Flash Attention 自定义算子。GPU 场景走F.scaled_dot_product_attention/flashmask 等路径,NPU 场景走flash_attention_npu,各后端互不干扰,这正是"仅修改 device 即可迁移"的底层保证。
融合 RMSNorm 的 GCU 分支
同理,paddlenlp/transformers/llama/fusion_ops.py 中的fusion_rms_norm针对 GCU 设备调用core.eager._run_custom_op("rms_norm_gcu", ...),而 GPU 等其他设备则回退到fused_ln.fused_rms_norm或paddle.incubate中的融合实现。模型层在config.use_fused_rms_norm为真时才会走这条融合路径(见 paddlenlp/transformers/llama/modeling.py)。
融合 RoPE 的设备白名单
use_fused_rope的开关逻辑在 paddlenlp/transformers/llama/modeling.py 中:当配置开启融合 RoPE 时,若当前设备不属于["npu", "mlu", "xpu", "gcu", "intel_hpu"]白名单,会打印警告并自动降级为普通实现;GCU 在白名单内,因此会直接使用fused_rotary_position_embedding(见 paddlenlp/transformers/llama/modeling_network.py)。值得注意的是,融合 RoPE 当前不支持带 past_key_value 的缓存分支(源码中assert past_key_value is None),评估场景恰好满足该前提。
QKV 与 FFN 投影融合
fuse_attention_qkv:在 paddlenlp/transformers/llama/modeling.py 中,开启后将 Q/K/V 三个独立Linear合并为一个输出维度为hidden_size + 2 * num_key_value_heads * head_dim的qkv_proj,把三次矩阵乘合并为一次;源码同时做了约束检查——当num_key_value_heads % tensor_parallel_degree != 0时禁止开启,避免张量并行切分失败。fuse_attention_ffn:在 paddlenlp/transformers/llama/modeling.py 中,开启后将 FFN 的gate_proj与up_proj合并为gate_up_fused_proj(输出维度intermediate_size * 2),前向时直接对融合结果执行swiglu,减少一次矩阵乘与权重加载开销。
由于推理评估是计算密集型任务,上述融合算子能显著减少 kernel 启动次数、权重搬运与中间张量,这正是文档建议"首次下载权重后修改配置"以获取更大性能提升的原因。
常见问题与注意事项
- 首次运行会自动下载权重:权重缓存于
/root/.paddlenlp/models/__internal_testing__/sci-benchmark-llama-13b-5k/,务必在下载完成后、正式推理前修改config.json以启用融合算子。 - 版本匹配:文档流程基于 PaddlePaddle 3.0.0b0、PaddleCustomDevice v3.0.0-beta1、PaddleNLP v3.0.0-beta0 组合验证,编译时需按上文步骤切换到对应分支。
- 日志与调试:推理日志重定向到
wikitext_eval_gcu.log,评估结束后可tail该文件查看 ppl 汇总结果;若怀疑某个算子不兼容,可调整CUSTOM_DEVICE_BLACK_LIST将对应算子加入黑名单回退到默认实现。 - GCU 与 GPU 的迁移成本:只需将评估脚本中
--device gpu改为--device gcu,其余推理流程(模型加载、数据、指标计算)完全一致;融合算子分发由get_env_device()自动完成。
小结
通过本文,你已完整掌握在燧原 S60 上使用 PaddleNLP 运行 Llama2-13B 的完整链路:从驱动与燧原软件栈安装、PaddleCustomDevice 源码编译,到 wikitext-103 数据准备与 ppl 评估;并理解了use_flash_attention、use_fused_rope、use_fused_rms_norm、fuse_attention_qkv、fuse_attention_ffn五个融合配置在 GCU 后端的真实调用路径(fused_sdp_flash_attention_gcu、rms_norm_gcu、fused_rotary_position_embedding等自定义算子)。在此基础上,你可以将此流程推广到仓库中其他模型,仅需替换模型名与设备参数即可完成 GCU 上的推理迁移。
- 人工智能
- 大模型
- 预训练
- 微调
- LoRA
- RLHF
- 强化学习
- 分布式训练
【免费下载链接】PaddleNLP
Easy-to-use and powerful LLM and SLM library with awesome model zoo.
相关推荐
在燧原 S60(GCU)上使用 PaddleNLP 运行 llama2-13B 模型:从环境搭建到 Wikitext 评测
在燧原 S60(GCU)上使用 PaddleNLP 运行 llama2 13B 模型:从环境搭建到 Wikitext 评测 燧原 S60 是面向数据中心大规模部
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPPaddleNLP 在燧原 GCU 上运行 Llama2-13B 推理部署全指南
PaddleNLP 在燧原 GCU 上运行 Llama2 13B 推理部署全指南 PaddleNLP 已完成对燧原 S60 推理加速卡(GCU)的深度适配,通过
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPPaddleNLP 在海光 DCU 上运行 Llama2-13B:环境搭建、微调、预训练与高性能推理实战指南
PaddleNLP 在海光 DCU 上运行 Llama2 13B:环境搭建、微调、预训练与高性能推理实战指南 本文档完整讲解如何使用 PaddleNLP 在海光
人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考