From 5f1b103c47a92be8441d9b2660437d3a9b275e09 Mon Sep 17 00:00:00 2001 From: YangWencheng Date: Fri, 20 Jun 2025 16:32:26 +0800 Subject: [PATCH] Add large mode inference on multiple nodes based on CSV --- ...346\234\272\347\233\264\351\200\232DCU.md" | 412 +++++++++++++++++- 1 file changed, 388 insertions(+), 24 deletions(-) diff --git "a/sig/Hygon Arch/content/2-CSV\346\265\213\350\257\225\346\226\207\346\241\243/3-\350\231\232\346\213\237\346\234\272/4-\346\265\213\350\257\225CSV\350\231\232\346\213\237\346\234\272\347\233\264\351\200\232DCU.md" "b/sig/Hygon Arch/content/2-CSV\346\265\213\350\257\225\346\226\207\346\241\243/3-\350\231\232\346\213\237\346\234\272/4-\346\265\213\350\257\225CSV\350\231\232\346\213\237\346\234\272\347\233\264\351\200\232DCU.md" index a627802e0..a7b1cfda7 100644 --- "a/sig/Hygon Arch/content/2-CSV\346\265\213\350\257\225\346\226\207\346\241\243/3-\350\231\232\346\213\237\346\234\272/4-\346\265\213\350\257\225CSV\350\231\232\346\213\237\346\234\272\347\233\264\351\200\232DCU.md" +++ "b/sig/Hygon Arch/content/2-CSV\346\265\213\350\257\225\346\226\207\346\241\243/3-\350\231\232\346\213\237\346\234\272/4-\346\265\213\350\257\225CSV\350\231\232\346\213\237\346\234\272\347\233\264\351\200\232DCU.md" @@ -1,6 +1,6 @@ 测试之前,请参考[2-1-安装CSV软件](https://openanolis.cn/sig/Hygon-Arch/doc/865622260278236994?lang=zh)准备软件环境。 -# 功能描述 +# 1. 功能描述 某些应用场景需要在CSV虚拟机中运行图像识别、机器学习等算法,这些场景下使用DCU加速卡可以极大地提高计算性能,CSV虚拟机支持设备直通,可以将DCU卡直通给CSV虚拟机使用。 @@ -24,11 +24,11 @@ -# 测试DCU直通CSV虚拟机 +# 2. 测试DCU直通CSV虚拟机 -## 搭建测试环境 +## 2.1. 搭建测试环境 -### Host启动CSV虚拟机 +### 2.1.1. Host启动CSV虚拟机 * Host上安装DCU的fixup header插件 @@ -166,7 +166,7 @@ 虚拟机启动后,登录虚拟机,可以通过命令`lspci`查看到DCU设备,说明DCU直通CSV虚拟机成功。 -### 在CSV虚拟机中安装DCU环境 +### 2.1.2. 在CSV虚拟机中安装DCU环境 这一小节说明如何在虚拟机中安装DCU的运行环境,包括安装驱动、DTK软件栈和环境配置。 @@ -243,7 +243,7 @@ 其他的shell,如zsh, csh请自行添加到对应的shell初始化文件中。 -## 在CSV虚拟机中运行DCU测试程序 +## 2.2. 在CSV虚拟机中运行DCU测试程序 这里使用一个简单的向量加法示例演示DCU并行计算。在CSV虚拟机中下载`HIP-Examples`仓库,编译、运行其中的`vectorAdd`测试程序。 @@ -263,7 +263,7 @@ PASSED! -## 在CSV虚拟机中运行Qwen大模型 +## 2.3. 在CSV虚拟机中运行Qwen大模型 本节演示在CSV虚拟机中基于ollama运行Qwen大模型,内容包括安装安装go、安装gcc-10、python3.10、安装pytorch、编译ollama、运行Qwen大模型。 @@ -451,13 +451,378 @@ PASSED! ``` -# 测试全机密模式 + +## 2.4. 基于CSV的多节点推理 + +### 2.4.1. 背景 + +小模型可以在单个DCU卡上运行,大模型通常需要在多个DCU卡,甚至多个节点才能上运行,比如deepseek满血版671B。 + +已知多节点大模型在host机器上可以运行,普通虚拟机和CSV虚拟机上鲜有公开资料记录。经过尝试,在普通虚拟机或CSV虚拟机上运行多节点大模型推理是可行的。在此记录如何在多节点环境上基于CSV虚拟机运行大模型推理。 + +### 2.4.2. 测试环境说明 + +- 2台机器,每台配备8张K100的DCU卡,2台机器通过网络互联 +- host OS: ubuntu20.04, anolis 8.4均可,只要能运行CSV虚拟机即可。 +- host kernel: 5.10 +- guset OS: ubuntu20.04, anolis 8.4均可 +- guest kernel: 5.10 +- DCU驱动:rock-5.7.1-6.2.31.aio.run,从光合组织上下载。 +- DTK:docker容器镜像提供,无需单独安装 + +### 2.4.3 搭建环境 + +#### 2.4.3.1 host环境 + +参考2.1节搭建host的测试环境,保证DCU卡可以直通到CSV虚拟机中。 + +#### 2.4.3.2 运行CSV虚拟机 + +CSV节点之间通过网络互联,所以需要配置虚拟机的网络,使得在虚拟机里面多个节点的网络是连通的。可以使用网卡直通到虚拟机,或者使用virtio-net虚拟网卡,二者选一个即可。 + +##### 2.4.3.2.1. 网卡直通 + +相比虚拟网卡,网卡直通到虚拟机性能要好一些。网卡直通和DCU直通在原理上是一致的,内容包括将网卡和网卡驱动解绑,然后将网卡和vfio驱动绑定,最后在qemu的启动参数中添加网卡直通的参数。 + +- 解绑网卡驱动 + + **比如**网卡设备对应BDF为91:00.0,vid did 为15b3 1015 ,那么先获取它的驱动。 + + ```sh + $ echo "0000:91:00.0" | sudo tee /sys/bus/pci/devices/0000:91:00.0/driver/unbind + ``` + +- 网卡绑定到vfio驱动 + + ```sh + $ echo 15b3 1015 | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id + ``` + +- 网卡直通的qemu启动参数 + + ```sh + $ /qemu-system-x86_64 ... -device vfio-pci,host=0000:91:00.0 ... + ``` + + 如果有多个网卡需要直通,需要将这些网卡都帮绑定到网卡驱动,启动虚拟机的时候,在qemu的参数中添加这些网卡。 + +##### 2.4.3.2.2 虚拟网卡 + +如果网卡直通不可行,那么使用虚拟网卡是个替代方案。虚拟网卡的示意图如下,假设系统上有硬件网卡ens0,我们需要在虚拟机中使用虚拟网卡,底层使用真实的硬件网卡。 + +``` + +----------------+ + | eth0 | + +----------------+ VM +---------------|--------------- + +----------------+ + | TAP0 | + +----------------+ + | + +----------------+ + | BRIDGE | + +----------------+ + | + +----------------+ + | ens0 | + +----------------+ +``` + +- 创建bridge + + 先在host上创建一个bridge,然后将硬件网卡和bridge关联在一起。 注意将脚本中的ETH=ens0更改为你的网卡名称(通过ifconfig可以查看到)。 + + ```sh + #!/bin/bash + + # setup br0 + BRIDGE=br0 + ETH=ens0 + # create bridge br0 + sudo ip link add $BRIDGE type bridge + # briing up BRIDGE + sudo ifconfig $BRIDGE up + # bring down ETH + sudo ifconfig $ETH down + # clear ETH IP + sudo ip addr flush dev $ETH + # add eth0 into br0 + sudo ip link set $ETH master $BRIDGE + # bring up ETH + sudo ifconfig $ETH up + # assign IP to BRIDGE + #sudo dhclient -v $BRIDGE + sudo ifconfig $BRIDGE 192.168.1.100 + ``` + + **注意:两台机器上,给bridge配置不同的IP地址,例如我们给一台机器上的bridge配置IP地址为192.168.1.100,另一台机器的bridge配置IP为192.168.1.200。** + +- 创建qemu-ifup.sh和qemu-ifdown.sh + + 创建两个脚本,qemu_ifup.sh和qemu-ifdown.sh,用于qemu在启动时床架的tap设备加入到bridge中来,qemu退出时将设备移除bridge。 + + qemu-ifup.sh内容如下: + + ```sh + #!/bin/bash + + switch=br0 + if [ -n "$1" ]; then + ip tuntap add dev $1 mode tap + ip link set $1 up + ip link set $1 master ${switch} + exit 0 + else + echo "Error: no interface specified" + exit 1 + fi + ``` + + qemu-ifdown.sh内容如下: + + ```sh + #!/bin/bash + + switch=br0 + + if [ -n "$1" ]; then + brctl delif ${switch} $1 + #shutdown the TAP interface + ip link set $1 down + exit 0 + else + echo "Error: no interface specified" + exit 1 + fi + ``` + +- qemu启动参数 + + 注意,**需要修改多个节点上虚拟机的参数中网卡的mac地址,避免mac地址重复** + + ```sh + $ sudo qemu-system-x86_64 ... \ + -netdev tap,id=net0,script=qemu-ifup.sh,downscript=qemu-ifdown.sh \ + -device virtio-net-pci,netdev=net0,mac=e8:61:1f:6c:24:e3 \ + ... + ``` + +#### 2.4.3.3 虚拟机环境配置 + +例如,使用虚拟网卡,直通8张DCU卡到CSV虚拟机,qemu启动脚本如下: + +```sh +#!/bin/bash + +IMAGE=focal-server-cloudimg-amd64.img +PORT=2222 + +sudo qemu-system-x86_64 \ + -drive file=$IMAGE \ + -enable-kvm -m 200G -cpu host -smp 64 -nographic \ + -drive if=pflash,format=raw,unit=0,file=OVMF_CODE.fd,readonly=on \ + -netdev tap,id=net0,script=qemu-ifup.sh,downscript=qemu-ifdown.sh \ + -device virtio-net-pci,netdev=net0,mac=e8:61:1f:6c:24:e3 \ + -net nic -net user,hostfwd=tcp::$PORT-:22 \ + -device vfio-pci,host=0000:07:00.0 \ + -device vfio-pci,host=0000:0a:00.0 \ + -device vfio-pci,host=0000:0f:00.0 \ + -device vfio-pci,host=0000:16:00.0 \ + -device vfio-pci,host=0000:1d:00.0 \ + -device vfio-pci,host=0000:20:00.0 \ + -device vfio-pci,host=0000:25:00.0 \ + -device vfio-pci,host=0000:2c:00.0 \ + -fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=1048560 +``` + +**为了统一环境配置,以下的操作,都是在虚拟中使用root用户操作。此处我们命名两台CSV分别为master节点和node1从节点。** + +虚拟机启动后,在虚拟机中安装DCU驱动,驱动选择下载rock-5.7.1-6.2.31.aio.run。 + +在虚拟机中安装docker环境,参考:https://docs.docker.com/engine/install/ubuntu/ + +- 给CSV虚拟机网卡配置IP地址 + + 假设CSV虚拟机中我们要配置的网卡为eth0,由于这个网卡和对端网卡是直连的,没有DHCP server,需要我们手动为期配置IP地址。 + + **配置CSV-A的IP地址配置为192.168.1.102,CSV-B为192.168.1.202。** + + 例如,在master节点上执行下面命令配置IP地址: + + ```sh + $ ifconfig eth0 192.168.1.102 + ``` + + 在node1节点上执行: + + ```SH + $ ifconfig eth0 192.168.1.202 + ``` + + 此时,两台CSV之间应当可以互相ping通。 + +- 设置节点名 + + 在master节点和node1节点上,打开/etc/hosts文件,添加如下内容: + + ```sh + 192.168.1.102 master + 192.168.1.202 node1 + ``` + +- 配置两台CSV虚拟之间ssh免密登录 + + 在master节点上执行下面命令,用来使能ssh免密登录 + + ```sh + $ ssh-copy-id root@node1 + # verify password free login is effective + $ ssh node1 + ``` + + 在node1节点上执行: + + ```sh + $ ssh-copy-id root@master + # verify password free login is effective + $ ssh master + ``` + +### 2.4.4. docker容器内多节点推理 + +* docker拉取容器镜像 + + 这个容器镜像是vllm的容器,其中安装了vllm的环境,DTK环境。 + + ```sh + $ docker pull image.sourcefind.cn:5000/dcu/admin/base/custom:vllm0.8.5-ubuntu22.04-dtk25.04-rc7-das1.5-py3.10-20250521-fixpy-rocblas0521-beta2 + ``` + +* 下载deepseek 模型 + + 作为演示,我们使用DeepSeek-R1-Distill-Llama-70B模型,从https://www.modelscope.cn/models/deepseek-ai/DeepSeek-R1-Distill-Llama-70B/files下载,**保存到CSV虚拟机的/root/models目录下**。文件较大,下载需要一段时间。 + +* 启动docker 容器 + + 在两台CSV虚拟机中,分别启动docker容器。 + + ```sh + $ docker run -dit --network=host --name=deepseek_test --privileged \ + --device=/dev/kfd --device=/dev/dri --device=/dev/mkfd \ + --ipc=host --shm-size=256G --group-add video \ + --cap-add=SYS_PTRACE --security-opt seccomp=unconfined \ + -u root \ + --ulimit stack=-1:-1 --ulimit memlock=-1:-1 \ + -p 2222:22 -p 6480:6480 \ + -v /opt/hyhal:/opt/hyhal:ro -v /root/models:/workspace -v /root/.ssh:/root/.ssh \ + image.sourcefind.cn:5000/dcu/admin/base/custom:vllm0.8.5-ubuntu22.04-dtk25.04-rc7-das1.5-py3.10-20250521-fixpy-rocblas0521-beta2 \ + bash + ``` + + 主要参数说明: + + 1. --name=deepseek_test 设置容器名为deepseek_test,后面使用该名操作容器。 + 2. -v /root/.ssh:/root/.ssh 将CSV虚拟机root的ssh文件挂载到容器中,使得容器中使用CSV虚拟机root用户的ssh配置。我们在上面配置的CSV虚拟机root用户的免密登录,在容器中也使用免密登录。 + 3. --device=/dev/kfd --device=/dev/dri --device=/dev/mkfd 是DCU驱动在CSV虚拟上生成的文件,需要将这些文件挂载到容器中。 + 4. -v /opt/hyhal:/opt/hyhal:ro 将host上DCU驱动安装的目录/opt/hyhal挂载到容器,容器中DCU的软件栈需要使用这个目录。 + 5. -v /root/models:/workspace 将CSV虚拟机上的模型文件挂载到容器的/worksapce目录。 + 6. -p 6480:6480 将host的6480端口映射到容器的6480端口,该端口用于多节点之间通信。 + +* docker 环境初始化 + + 通过以下命令进入docker bash + + ```sh + $ docker exec -it deepseek_test bash + ``` + + 在docker bash中使能sshd,设置。将下面文本保存到**setup_env.source**文件 + + ```sh + /usr/sbin/sshd -p 2222 + hy-virtual -enable-encrypted + export ALLREDUCE_STREAM_WITH_COMPUTE=1 + # 设置当前容器网卡的IP 地址 + export VLLM_HOST_IP=192.168.1.102 + # 设置网卡名称 + export NCCL_SOCKET_IFNAME=eth0 + export GLOO_SOCKET_IFNAME=eth0 + export HIP_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 + export VLLM_RPC_TIMEOUT=1800000 + # export NCCL_ALGO=Ring + export NCCL_ALGO=Tree,Ring + # 0.7.2 vllm 设置 + export VLLM_MLA_DISABLE=1 + + rocm-smi --setperflevel high + rocm-smi --setsclk 10 + rocm-smi --setsocclk 7 + ``` + + 注意:**修改文本中的IP地址为本节点对应的IP地址**。 + + **第一次进入docker bash的时候使用该文本初始化环境变量**,不用每次进入docker bash都初始化。 + + ```sh + $ source setup_env.source + ``` + +* 启动节点 + + 先在master节点(IP地址为192.168.1.102)上执行以下命令,启动master节点。 + + ```sh + $ ray start --head --node-ip-address='192.168.1.102:6480' --num-gpus=8 --num-cpus=32 + ``` + + 注意其中的的端口号和启动docker命令中的端口保持一致。 + + 在node1节点上上执行一下命令,启动从节点。如有多个从节点,依次在从节点上执行。 + + ```sh + $ ray start --address='192.168.1.102:6480' --num-gpus=8 --num-cpus=32 + ``` + + 注意从节点上IP地址指向主节点的IP地址。 + + 节点启动后,在容器内通过/opt/hyhal/bin/hy-smi命令可以看到DCU的VRAM占有率开始增长。 + +* 在主节点上容器内启动推理 + + ```sh + #!/bin/bash + + vllm serve /workspace/DeepSeek-R1-Distill-Llama-70B \ + --trust-remote-code --distributed-executor-backend ray --dtype float16 \ + --max-model-len 50000 -tp 16 --gpu-memory-utilization 0.95 \ + --max-num-seqs 128 --served-model-name ds70b --port 8000 + ``` + + 注意命令中的模型地址。模型对外的端口为8000,后面使用该端口和模型交互。 + +* 在主节点上测试推理 + + 模型加载可能需要一些时间,等加载完毕,就可以在**master主节点**上测试推理。在master主节点上,另外开启一个docker bash,执行下面命令测试推理。 + + ```sh + $ docker exec -it deepseek_test bash + + root@ubuntu:/workspace# + $ curl -X POST -H "Content-Type:application/json" http://0.0.0.0:8000/v1/chat/competions \ + -d '{"model": "ds70b","messages": [{"role": "user","content": "帮我写一篇桃花盛宴记"}],"stream":false }' + ``` + + 如果模型加载未完成,执行这个命令将会返回错误“curl: (7) Failed to connect to 0.0.0.0 port 8000: Connection refused”。 + + + +# 3. 测试全机密模式 本节在CSV虚拟机中测试DCU传输加密和显存隔离功能。要求在CSV中安装了DCU的软件栈,参考**2.1节搭建测试环境**。 > 提示:**测试以K100 DCU卡为例,如果使用其他型号的DCU卡请联系海光securitytech@hygon.cn获取对应的软件栈。** -## 更新DCU驱动 +## 3.1. 更新DCU驱动 将host上的文件`k100_update_driver.sh`传输到CSV,更新CSV中的DCU驱动。 @@ -468,7 +833,7 @@ $ cd /root $ ./k100_update_driver.sh ``` -## 更新DCU的vBIOS +## 3.2. 更新DCU的vBIOS 全机密模式依赖DCU的vBIOS,需要使用支持全机密的vBIOS。 @@ -479,7 +844,7 @@ $ ./hyflash --index 0 --update ./KM/ai-k100-8275-5.715.001200k.618009-dcurom.bin 更新完成DCU的vBIOS,最好给机器下电,再上电,使得新的vBIOS生效。 -## 更新DTK +## 3.3. 更新DTK 将host上的文件`k100_update_dtk.sh`传输到CSV,更新CSV中的DTK。 @@ -490,7 +855,7 @@ $ cd /root $ ./k100_update_dtk.sh ``` -## 部署大模型 +## 3.4. 部署大模型 ```sh $ systemctl start docker @@ -500,14 +865,14 @@ $ cd /root/ $ python3 -m vllm.entrypoints.api_server --model Qwen/Qwen2.5-3B --tensor-parallel-size 1 --gpu-memory-utilization 0.9 --trust-remote-code --dtype auto --enforce-eager ``` -## 调用大模型 +## 3.5. 调用大模型 ```sh $ docker exec -it dcu_vllm /bin/bash $ curl http://localhost:8000/generate -H "Content-Type: application/json" -d '{"prompt": "hello","max_tokens": 128,"temperature": 0.7}' ``` -## 检查软件栈中的加密日志 +## 3.6. 检查软件栈中的加密日志 CPU和DCU之间传输的数据被软件栈加密,可以看到如下的日志输出。 @@ -518,15 +883,15 @@ Transfer data from DCU to CPU, Data size: 0x800, Encrypt using SM4 -# 测试 DCU Attestation +# 4. 测试 DCU Attestation -## 背景 +## 4.1. 背景 从深算二号(K100-AI)开始,海光DCU开始支持Attestation(身份认证)功能,DCU Attestation的目的是向DCU加速器的使用者证明,正在使用中的DCU设备具有真实身份,其芯片ID、固件版本、硬件环境等相关数据皆为真实可信,用户可将机密数据下发到DCU中计算,无需担心数据被恶意的加速器窃取。 DCU驱动从 rock-kernel-refactory-rock-5.7.1-6.2.26-V1.5.aio.run 开始支持Attestation功能,对应的驱动可以从 [光合组织]( https://cancon.hpccube.com:65024/6/main)下载。 -## 认证机制 +## 4.2. 认证机制 每一颗DCU芯片拥有唯一的芯片ID(ChipID),在芯片生产时烧入,以后无法更改。芯片内置一SM2密钥对(DCEK, DCU Chip Endorsement Key),私钥作为DCU芯片的身份象征,只保存在DCU芯片,永不外泄。公钥被HDSK(海光DCU签名密钥)/HRK(海光根密钥)签名后,存放于海光证书系统中,可公开下载。 @@ -542,7 +907,7 @@ DCU驱动从 rock-kernel-refactory-rock-5.7.1-6.2.26-V1.5.aio.run 开始支持At 海光提供了Attestation demo,演示了CSV虚拟机用户向DCU请求认证报告、获取认证报告、下载证书链、验证远程报告、验证证书链的全过程。该demo程序仅做展示,用户可根据需要修改或重新编写。 -## 测试 +## 4.3. 测试 请依据[4-测试CSV虚拟机直通DCU](https://openanolis.cn/sig/Hygon-Arch/doc/865622222638552866?lang=zh) 搭建环境。 @@ -567,14 +932,14 @@ DCU驱动从 rock-kernel-refactory-rock-5.7.1-6.2.26-V1.5.aio.run 开始支持At ```sh $ ./dcu_attestation_demo ``` - + 该程序会打印出DCU ChipID,并打印证书下载失败的日志,然后退出。 - + ```sh chip_id T6N69800002080601 ``` - + 如上日志所示,该DCU的ChipID为”T6N6980002080601”。 2. 在attestation下,手动下载该芯片的HSK_CEK证书 @@ -582,7 +947,7 @@ DCU驱动从 rock-kernel-refactory-rock-5.7.1-6.2.26-V1.5.aio.run 开始支持At ```sh $ curl -s -f -o hsk_cek.cert https://cert.hygon.cn/hsk_cek?snumber=T6N6980002080601 ``` - + 命令完成后,在当前目录下生成hsk_cek.cert文件,文件包含HSK证书和CEK证书。 3. 在attestation下,手动下载HRK证书 @@ -590,7 +955,7 @@ DCU驱动从 rock-kernel-refactory-rock-5.7.1-6.2.26-V1.5.aio.run 开始支持At ```sh $ curl -s -f -o ./hrk.cert https://cert.hygon.cn/hrk ``` - + 命令完成后,在当前目录下生成hrk.cert。 4. 再次运行attestation demo程序,完成DCU身份验证 @@ -599,4 +964,3 @@ DCU驱动从 rock-kernel-refactory-rock-5.7.1-6.2.26-V1.5.aio.run 开始支持At $ ./dcu_attestation_demo ``` - -- Gitee