华为显卡部署DeepSeek-R1-Distill-Qwen-32B记录

记录一次在华为显卡上部署DS 32B蒸馏模型的过程,主要是一些注意事项和报错处理。报错处理是咨询DS老师(DeepSeek)得知怎么处理的。

部署参考文章

部署主要是参考了昇腾社区和魔乐社区大佬的教程,两篇文章内容是一致的,链接如下:

昇腾社区:DeepSeek-R1-Distill-Qwen-32B-模型库-ModelZoo-昇腾社区
魔乐社区:MindIE/DeepSeek-R1-Distill-Qwen-32B | 魔乐社区

注意事项及报错整理(按文章顺序,没提到的就按文章进行操作)

1 权重无需转换

由于蒸馏版本的模型本质上还是Qwen2.5模型,模型权重文件格式为.safetensor格式,所以无需转换。

那么如果是部署的DeepSeek-R1或V3模型,则需要进行权重转换,具体请参考下面这篇文章。或者在昇腾社区的Modelzoo中搜索ds系列模型参考。

DeepSeek-R1部署:DeepSeek-R1-模型库-ModelZoo-昇腾社区

2 获取镜像

通过文章链接去下载对应的镜像,需要根据你所实际部署时的机器来决定,我这里是在一台Atlas 300I DUO服务器上进行部署的,镜像选的是1.0.0-300I-Duo-py311-openeuler24.03-lts。需要先申请权限,得到权限后可以直接进行docker pull操作。直接pull下来的镜像就无需像文章中先docker load了,直接创建容器即可。(一定要pull正确的镜像)

3 新建容器

REPOSITORY和TAG通过docker images查看后,复制贴到下面命令对应位置。<container-name>给容器取个名。权重文件路径记得替换。

注:以下bash命令是在root权限下创建的容器,如果不是root,请参考文章中非root权限对应命令。

docker run -it -d --net=host --shm-size=1g \
    --privileged \
    --name <container-name> \
    --device=/dev/davinci_manager \
    --device=/dev/hisi_hdc \
    --device=/dev/devmm_svm \
    -v /usr/local/Ascend/driver:/usr/local/Ascend/driver:ro \
    -v /usr/local/sbin:/usr/local/sbin:ro \
    -v ${path-to-weights}:${path-to-weights}:ro \
    ${REPOSITORY}:${TAG} bash

4 服务化部署

认证文件缺失错误

需要特别注意的是,在修改config.json文件时,httpsEnabled参数一定要记得改成false,关闭tls https认证。

"httpsEnabled" : false

 如果没有修改的话,在拉起服务的时候会有tls https认证,然后会出现一系列认证文件缺失的错误,如下。

当然了,也可以补全这些认证文件(主要是一些密钥),会花费一些时间,且需要根据实际的认证需求来考虑。

错误日志不打印-不会自动生成mindservice.log文件错误

在服务拉起过程中,命令行输出的日志中可能会出现关于日志记录的错误,如下。显示Unicode编码错误。不解决的话也不会影响服务的正常启动和模型的推理,但是会无法查看到生成的错误日志!

这里咨询了DS老师,按照接下来的操作对日志记录路径下的两个py文件进行小改即可解决。

/usr/local/Ascend/atb-models/atb_llm/utils/log

第一步:修改日志流的编码 StreamHandler

1.修改SafeRotatingFileHandler的编码
在logging.py中,修改SafeRotatingFileHandler的_open方法,显式指定编码为utf-8

def _open(self):
    """
    Override:
        Open the current base file with the (original) mode and encoding.
        Modify the permissions of current files.
        Return the resulting stream.
    """
    if os.path.exists(self.baseFilename):
        file_utils.safe_chmod(self.baseFilename, MAX_OPEN_LOG_FILE_PERM)
    ret = self._builtin_open(self.baseFilename, self.mode, encoding='utf-8', errors='replace')
    file_utils.safe_chmod(self.baseFilename, MAX_OPEN_LOG_FILE_PERM)
    return ret

2.修改StreamHandler的编码
在logging.py中,修改init_logger函数中的StreamHandler初始化代码,显式指定编码为utf-8

if str(log_to_stdout).upper() in ["1", TRUE]: 
    # 添加控制台输出日志
    console_formatter = ErrorCodeFormatter()
    console_handle = logging.StreamHandler(stream)
    console_handle.setFormatter(console_formatter)
    console_handle.encoding = 'utf-8'  # 显式设置编码
    logger_ins.addHandler(console_handle)
第二步:过滤非ASCII字符

1.在日志记录前过滤非ASCII字符
在logging.py中,修改message_filter函数,增加对非ASCII字符的过滤:

def message_filter(msg: str):
    """
    Truncate message exceeding the limit and filter special characters.
    """
    if len(msg) > MAX_MSG_LEN:
        msg = msg[:MAX_MSG_LEN] + '...'
    for item in SPECIAL_CHARS:
        msg = msg.replace(item, ' ')
    msg = re.sub(r' {5,}', '    ', msg)
    # 过滤非ASCII字符
    msg = msg.encode('ascii', errors='ignore').decode('ascii')
    return msg

2.在日志记录时调用过滤函数
在logging.py中,确保所有日志记录都经过message_filter处理:

def print_log(rank_id, logger_fn, msg, need_filter=True):  # 默认启用过滤
    if rank_id != 0:
        return
    if need_filter:
        msg = message_filter(str(msg))
    logger_fn(msg)
第三步:修改MultiLoggingHandler的编码处理

在MultiLoggingHandler中显式设置编码
在multiprocess_logging_handler.py中,修改MultiLoggingHandler的emit方法,确保日志记录的编码为utf-8

def emit(self, record):
    """
    Emit a record.
    """
    try:
        sd_record = self._format_record(record)
        if isinstance(sd_record, str):
            sd_record = sd_record.encode('utf-8', errors='replace').decode('utf-8')
        self.send(sd_record)
    except KeyboardInterrupt as err:
        raise err
    except ValueError:
        self.handleError(record)

经过以上修改后,再次启动服务,在路径下应该就有mindservice.log日志文件了。

5 测试服务

服务启动后,可以通过文章的调用方式进行测试,也可以参考昇腾社区的文档多测试一下(TGI/vLLM/OpenAI/Triton/MindIE原生接口)。请在容器外/退出容器/另起一个命令行窗口进行测试。

文档链接:使用兼容OpenAI接口-接口调用-快速开始-MindIE Service开发指南-服务化集成部署-MindIE1.0.0开发文档-昇腾社区

注意:如果使用昇腾社区提供的推理接口命令测试,由于关闭了tls https认证,那么需要去除命令中的下述部分(用于认证的参数),并将最后的https请求改为http。

--cacert ca.pem --cert client.pem  --key client.key.pem

OpenAI请求样例:

curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{
 "model": <your-model-name, same as modelName in config.json>,
 "messages": [{
  "role": "system",
  "content": "You are a helpful assistant."
 }],
 "max_tokens": 20,
 "presence_penalty": 1.03,
 "frequency_penalty": 1.0,
 "seed": null,
 "temperature": 0.5,
 "top_p": 0.95,
 "stream": false
}' http://${host}:${port}/v1/chat/completions

6 待解决:可能是NPU间的通信问题?(已解决)

我部署的服务器中一共是两张NPU,4个Device,在部署过程中,我将config.json文件中调整npuDeviceIds为[[0,1,2,3]],worldSize为4;服务化部署正常拉起,但是发起请求则会报错,如下图。但是如果调整npuDeviceIds为[[0,1]],worldSize为2,即在同一张NPU上启动服务,再请求推理是ok的。没有能达到文章中的同样的效果("npuDeviceIds" : [[0,1,2,3]],"worldSize" : 4)。感觉可能是NPU通信的问题,或者哪里配置错了。

目前还在寻找解决方案。

-------------------------------------------------更新线-------------------------------------------------

解决方案 

咨询了华为的技术人员后,问题原因可能在于机器安装的驱动版本太老了,这里机器上原本安装的是23.0.1版本的驱动。在卸载了旧版的驱动和固件后,再安装新驱动和固件就可以在多卡部署服务之后进行服务调用了。这里新驱动版本:24.1.0.1

注意:商用的安装包的下载是需要具备有下载权限的华为账号的,包下载请联系具有权限账户的人员或咨询华为的技术人员获得支持。

下载地址:华为 Ascend HDK 软件下载和补丁升级-华为

选择对应的驱动版本,下载driverfirmwaremcu三个包。

新安装的驱动和固件包名:

Ascend-hdk-310p-npu-driver_24.1.0.1_linux-aarch64.run

Ascend-hdk-310p-npu-firmware_7.5.0.5.220.run

 其中需要确定的是驱动/固件对应的显卡型号安装包版本适配的系统架构,否则下载下后安装也会报错

驱动和固件安装指导:物理机安装与卸载 - Atlas 中心推理卡 24.1.0 NPU驱动和固件安装指南 02 - 华为

安装新驱动后成功部署:

发起请求可以成功调用:

 

### 华为Atlas平台上的DeepSeek模型部署 #### 准备工作 为了在华为Atlas平台上成功部署DeepSeek模型,需先完成必要的准备工作。这包括获取硬件支持以及软件环境配置。确保所使用的Atlas设备已连接至网络并能访问所需资源。 #### 软件安装与环境搭建 按照官方文档指示,在目标机器上安装Ascend Toolkit SDK及相关依赖库[^1]。此过程涉及设置Python虚拟环境、pip工具以及其他可能必需的组件。对于具体版本的选择,请参照项目仓库中的README文件说明来匹配兼容性要求。 #### 下载预训练模型权重 前往ModelScope网站下载适用于DeepSeek系列的大规模语言模型参数文件,例如`DeepSeek-R1-Distill-Qwen-32B`等变体。注意选择适合当前计算架构优化过的二进制格式以提高运行效率[^3]。 #### 配置推理服务接口 编写或调整现有的API脚本来加载上述获得的模型实例,并定义好输入输出的数据结构形式以便后续调用测试。可以考虑利用Flask框架快速构建RESTful Web Service端点实现在线预测功能。 ```python from transformers import AutoTokenizer, AutoModelForCausalLM import torch tokenizer = AutoTokenizer.from_pretrained("path/to/model") model = AutoModelForCausalLM.from_pretrained("path/to/model") @app.route('/predict', methods=['POST']) def predict(): input_text = request.json['text'] inputs = tokenizer(input_text, return_tensors="pt").to('cuda') outputs = model.generate(**inputs) result = tokenizer.decode(outputs[0], skip_special_tokens=True) return jsonify({"response":result}) ``` #### 性能监测与优化 引入Prometheus作为外部度量收集器用于跟踪NPU内存占用情况和数据处理速度变化趋势。依据实际应用场景需求适时调整批大小(batch size)或其他超参设定从而达到最佳性能表现。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值