志刚
发布于 2025-07-08 / 12 阅读
0
0

Qwen3-本地化部署

第一步:阿里云oss文件上下载到目标服务器

1.1 安装ossutil工具

先确认操作系统的版本 uname -m

● 若输出 x86_64,选择64位版本。

● 若输出 aarch64,选择ARM64版本。

1.2.下载ossutil工具

# 64位系统

wget http://gosspublic.alicdn.com/ossutil/1.7.14/ossutil64

 

# ARM64系统

wget http://gosspublic.alicdn.com/ossutil/1.7.14/ossutilarm64

1.3.授权

3. 赋予执行权限

chmod +x ossutil64 # 根据下载的文件名调整

1.4. 安装到系统路径(可选)

将文件移动到 /usr/local/bin,以便全局使用:

sudo mv ossutil64 /usr/local/bin/ossutil

1.5. 验证安装

bash

复制下载ossutil --version

1.6. 配置AccessKey

运行配置命令并按提示输入信息:

ossutil config

根据提示分别输入以下的信息,主要是endpoint和accessKeyID 和accesssKeySecret

[Credentials]

language = CH

#自己的oss站点

endpoint = https://oss-cn-wulanchabu.aliyuncs.com

#自己的oss里面的accessKey

accessKeyID = ***

#自己的oss里面的accessSecret

accessKeySecret = ****

1.7. 执行下载文件夹命令

参考: 通过cp命令将下载OSS的文件_对象存储(OSS)-阿里云帮助中心

整个文件夹copy

ossutil cp -r oss://towdisease/sft_model/0423v1/ sft_model/0423v1/
 
ossutil cp -r oss://llamafactory/export_train_models/qwen3-32b-520/  qwen3-32b-520/

单文件操作(由于整个文件夹中存在过程文件,不需要整个目录copy):

ossutil cp oss://towdisease/sft_model/0428  0428v1/ -r  --exclude "global_step594/**"  --exclude "checkpoint-500/**" --exclude "checkpoint-594/**"

 

 

第二步、开始部署脚本参考厂商提供的逻辑(VLLM方式)

mindie拉起vllm服务操作指导.docx

准备工作, 先拉起容器(本步骤运维已经做过,我们只需要去进入docker环境即可

docker exec -it 368ad24d3211 /bin/bash
先查看放上来的镜像
docker images
#新的镜像 QWQ-32B
新建容器
docker run -it -d --net=host --shm-size=800G \
   --privileged \
   --name DeepSeek \
   --device=/dev/davinci_manager \
   --device=/dev/hisi_hdc \
   --device=/dev/devmm_svm \
   -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
   -v /usr/local/sbin:/usr/local/sbin \
   -v /home:/home \
-v /dev/shm/:/dev/shm/ \
-v /mnt/:/mnt/ \
swr.cn-north-305.tjaicc.com/lhui/ascendhub/mindie:1.0.0-800I-A2-py311-openeuler24.03-lts bash
 #368ad24d3211 替换为创建完镜像返回的id 
docker exec -it 368ad24d3211 /bin/bash

2.1.安装vllm(特定厂商,需要特定脚本,不能自己乱安装)

按照厂商提供的vllm的文件夹压缩包进行解压后,运行命令

 

#1.先解压厂商给的特定的vllm版本
unzip vllm.zip
#2. 安装依赖包
pip install -r requirements-npu.txt
pip install transformers==4.45
#将vllm环境copy到python3.11下面去,此处碰到了之前存在会被覆盖的情况,如果存在,则先进行清除删除python3.11 包下面的vllm相关包
rm -rf /usr/local/lib64/python3.11/site-packages/vllm
rm -rf /usr/local/lib64/python3.11/site-packages/vllm*
#然后开始copy vllm包
cp -r vllm/vllm* /usr/local/lib64/python3.11/site-packages/
 

2.2. 修改启动模型服务脚本,解压厂商提供的vllm-MindIE-0.6.zip 解压,找到这个包下面的examples/start_server.sh 即可 修改如下参数:

export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3
python -m vllm.entrypoints.openai.api_server  \
       --model=/home/n1/sft_model/0423v1/sft_model/0423v1/ \
       --trust-remote-code \
       --enforce-eager \
       --max-model-len 8192 \
       --worker-use-ray \
       -tp 4 \
       --port 8080 \
       --block-size 128

此处还碰到一个问题,目前厂商给的卡只有0123 这四张卡能启动拉起来模型,使用后4张卡拉起直接不认识卡,跟厂商沟通,对方表示后4张貌似不是他们的,所以此处一定要使用前四张,改好脚本后,开始启动

bash examples/start_server.sh & # &代表后台启动 避免终端关了就不能用了
#启动后,日志目录是在如下目录进行查看
cd /root/mindie/log/debug
tail -200f mindie-llm_atbmodels_p_95800_202504251524.log

2.3. 启动过程中遇到了两个问题:

1. gpu 卡不能使用的问题,刚开始前4张卡被开源模型部署在使用,修改了启动卡为后4张卡,使用后四张卡启动报错,看日志类似卡驱动不能正常使用,问厂家无果,日志如下:

报错信息.txt

2. 于是沟通后,切到前4张卡去部署,碰到了第二个错误,启动的时候报内存不够,经过npu的内存查询,得知之前部署的服务kill后未自动释放npu的显存,于是找到使用npu的所有后台线程进行杀死(注意,必须退出docker环境,才能杀死进程

3. 使用 npu-smi info 查看使用的线程

 

第三步、由于vllm压测效果不佳,厂商又提供了他们封装后的针对qwq32b调优后的启动镜像

参考文档: DeepSeek-R1-Distill-Qwen-32B.doc

3.1. 先创建镜像,创建命令同第二步骤一样

#先查看厂商已经放上去的镜像
docker images

3.2.创建镜像,命令如下:

docker run -it -d --net=host --shm-size=800G \
   --privileged \
   --name DeepSeek \
   --device=/dev/davinci_manager \
   --device=/dev/hisi_hdc \
   --device=/dev/devmm_svm \
   -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
   -v /usr/local/sbin:/usr/local/sbin \
   -v /home:/home \
-v /dev/shm/:/dev/shm/ \
-v /mnt/:/mnt/ \
swr.cn-north-305.tjaicc.com/lhui/ascendhub/mindie:1.0.0-800I-A2-py311-openeuler24.03-lts bash

创建完成后会返回一个镜像id,根据镜像id进行启动进入镜像

#如果忘记了,也可以用一下命令查看你创建的镜像
docker ps 
#进入镜像
docker exec -it d66067722cb5 /bin/bash

 

3.3. 进入镜像后,先去修改config配置文件,

#配置缓存使用率
export NPU_MEMORY_FRACTION=0.96
 
cd /usr/local/Ascend/mindie/latest/mindie-service/conf/
vi config.json

重点修改如下(修改后的标红色,将修改前的值注释到后面):

 

{

"Version" : "1.1.0",

"LogConfig" :

{

"logLevel" : "Info",

"logFileSize" : 20,

"logFileNum" : 20,

"logPath" : "logs/mindservice.log"

},

 

"ServerConfig" :

{

"ipAddress" : "192.168.1.24",

"managementIpAddress" : "192.168.1.24",

"port" : 2025,

"managementPort" : 2026,

"metricsPort" : 2027,

"allowAllZeroIpListening" : true,

"maxLinkNum" : 1000,

"httpsEnabled" : false, #原值为true

"fullTextEnabled" : false,

"tlsCaPath" : "security/ca/",

"tlsCaFile" : ["ca.pem"],

"tlsCert" : "security/certs/server.pem",

"tlsPk" : "security/keys/server.key.pem",

"tlsPkPwd" : "security/pass/key_pwd.txt",

"tlsCrlPath" : "security/certs/",

"tlsCrlFiles" : ["server_crl.pem"],

"managementTlsCaFile" : ["management_ca.pem"],

"managementTlsCert" : "security/certs/management/server.pem",

"managementTlsPk" : "security/keys/management/server.key.pem",

"managementTlsPkPwd" : "security/pass/management/key_pwd.txt",

"managementTlsCrlPath" : "security/management/certs/",

"managementTlsCrlFiles" : ["server_crl.pem"],

"kmcKsfMaster" : "tools/pmt/master/ksfa",

"kmcKsfStandby" : "tools/pmt/standby/ksfb",

"inferMode" : "standard",

"interCommTLSEnabled" : false,

"interCommPort" : 1121,

"interCommTlsCaPath" : "security/grpc/ca/",

"interCommTlsCaFiles" : ["ca.pem"],

"interCommTlsCert" : "security/grpc/certs/server.pem",

"interCommPk" : "security/grpc/keys/server.key.pem",

"interCommPkPwd" : "security/grpc/pass/key_pwd.txt",

"interCommTlsCrlPath" : "security/grpc/certs/",

"interCommTlsCrlFiles" : ["server_crl.pem"],

"openAiSupport" : "vllm"

},

"BackendConfig" : {

"backendName" : "mindieservice_llm_engine",

"modelInstanceNumber" : 1,

"npuDeviceIds" : [[0,1,2,3,4,5,6,7]], #修改为8卡

"tokenizerProcessNumber" : 8,

"multiNodesInferEnabled" : false,

"multiNodesInferPort" : 1120,

"interNodeTLSEnabled" : false, #原值为true

"interNodeTlsCaPath" : "security/grpc/ca/",

"interNodeTlsCaFiles" : ["ca.pem"],

"interNodeTlsCert" : "security/grpc/certs/server.pem",

"interNodeTlsPk" : "security/grpc/keys/server.key.pem",

"interNodeTlsPkPwd" : "security/grpc/pass/mindie_server_key_pwd.txt",

"interNodeTlsCrlPath" : "security/grpc/certs/",

"interNodeTlsCrlFiles" : ["server_crl.pem"],

"interNodeKmcKsfMaster" : "tools/pmt/master/ksfa",

"interNodeKmcKsfStandby" : "tools/pmt/standby/ksfb",

"ModelDeployConfig" :

{

"maxSeqLen" : 32768, #最大的上下文长度

"maxInputTokenLen" : 8192, #最长的输入token长度

"truncation" : false,

"ModelConfig" : [

{

"modelInstanceType" : "Standard",

"modelName" : "qwq32b-sft", #对外调用的时候传递的模型名

"modelWeightPath" : "/home/n1/sft_model/0423v1/sft_model/0423v1/", #模型路径

"worldSize" : 8, #使用8卡,需要和上面的卡对上

"cpuMemSize" : 5,

"npuMemSize" : -1,

"backendType" : "atb",

"trustRemoteCode" : false

}

]

},

"ScheduleConfig" :

{

"templateType" : "Standard",

"templateName" : "Standard_LLM",

"cacheBlockSize" : 128,

 

"maxPrefillBatchSize" : 50,

"maxPrefillTokens" : 8192,

"prefillTimeMsPerReq" : 150,

"prefillPolicyType" : 0,

 

"decodeTimeMsPerReq" : 50,

"decodePolicyType" : 0,

 

"maxBatchSize" : 200,

"maxIterTimes" : 40960, #最大的输出长度,如果不改会被截断

"maxPreemptCount" : 0,

"supportSelectBatch" : false,

"maxQueueDelayMicroseconds" : 5000

}

}

}

3.4.替换掉微调后的模型文件中的config.json 和token.json 文件,这是厂商工程师多次尝试验证出来的,使用的是qwq32b 原模型的config.json 和token.json 文件来替换掉微调后的, 原模型文件如下:

config.jsontokenizer.json

对比了config.json 前后差异

 

3.5.启动模型服务

cd /usr/local/Ascend/mindie/latest/mindie-service/bin
#拉起服务
./mindieservice_daemon

当看到这些启动日志,就代表启动成功了

 

开源模型下载命令

参考他们的官网:MindIE/LLM/QwQ/QwQ-32B/README.md · Ascend/ModelZoo-PyTorch - Gitee.com

 

pip install modelscope
modelscope download --model Qwen/QwQ-32B --local_dir /mnt/n2
 

第四步 VLLM 方式启动qwen3-32B

#设置卡可见
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
# Update the vllm-ascend image
export IMAGE=quay.io/ascend/vllm-ascend:v0.8.4rc2
docker run --rm \
--name vllm-ascend3 \
--device=/dev/davinci0 \
--device=/dev/davinci1 \
--device=/dev/davinci2 \
--device=/dev/davinci3 \
--device=/dev/davinci4 \
--device=/dev/davinci5 \
--device=/dev/davinci6 \
--device=/dev/davinci7 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v /root/.cache:/root/.cache \
-v /mnt/n3:/mnt/n3 \
-p 8000:8000 \
-it $IMAGE bash
 
vllm serve /mnt/n3/qwen3/qwen3-32b --tensor-parallel-size 8 &

 

启动后优化模型中的参数:

防止死循环重复生成参数,修改 model 文件中generation_config.json 文件,增加如下配置

 "presence_penalty":1.06,

第五步、启动后如何调用

参考官方文档,写的很抽象,于是研究一番,经过总结,写了两种调用方式,一种http post, 一种兼容openai方式调用,调用代码如下:

官方文档链接: 推理接口-vLLM兼容OpenAI接口-EndPoint业务面RESTful接口-服务化接口-MindIE Service开发指南-服务化集成部署-MindIE1.0.0开发文档-昇腾社区

 

参考资料汇总:

1. 性能调优参数:性能调优流程-性能调优-MindIE Service-MindIE2.0.RC1开发文档-昇腾社区

2. 性能调优流程:

3. 性能调优流程-性能调优-MindIE Service-MindIE2.0.RC1开发文档-昇腾社区


评论