qwen 模型 MindIE PD 分离部署问题定位
背景
使用 MindIE 提供的 PD 分离特性部署 qwen2-7B 模型,使用 k8s 拉起容器,参考这个文档进行部署:https://www.hiascend.com/document/detail/zh/mindie/100/mindieservice/servicedev/mindie_service0060.html,1 个 Prefill,1 个 Decode。
最后一步测试推理请求的时候,出现报错:model instance has been finalized or not initialized。
排查过程
不管发生什么,不要慌,首先要看日志,重点看看有没有 fail、error 等关键字。
P 节点和 D 节点都是用 mindieservice-daemon 起的服务,最后打印了”daemon start success!“,看上去没有问题,但是用 npu-smi info 查看昇腾卡的显存占用,发现没有显存被占用,说明模型没有加载,和上面的报错信息逻辑对上了。
于是继续看 controller 和 coordinator 的启动日志。其实有一定经验后,通过”model instance has been finalized or not initialized“就知道应该是 controller 出问题了,因为 controller 负责 PD 身份决策与下发,coordinator 是数据面入口,用于对用户的请求输入进行调度。果然,在 controller 的日志里面发现这一一行 Error 日志:IsValidServer: server ip 10.xxx has invalid device num。这说明,controller 在尝试分配 P 或者 D 的时候,发现某个节点上没有可用的 device。由于 device 的信息是在 rank_table 文件中配置的,所以下一步需要检查 rank_table 文件。
果然,打开 rank_table 文件一看,发现 rank_table 文件中没有 device 字段!这样的话 controller 广播给 P 和 D 的 rank_table 中就缺失了 device 信息,导致 P 和 D 的 server 启动找不到昇腾卡。
根因找到了就好办了。
解决方案
对开发者最友好的方案,当然是修改 MindIE 镜像 /usr/local/Ascend/mindie/latest/mindie-service/examples/kubernetes_deploy_scripts/gen_ranktable_helper 目录下的 gen_global_ranktable.py 文件。但是为了快速解决问题,我们手动获取 device 字段的信息,再添加到 rank_table 中。
device 字段的格式如下:
由于客户使用了 k8s 进行容器化部署,而 device 的 device_ip 信息在宿主机的/etc/hccn.conf 文件中,所以我们可以在创建容器的时候,把宿主机的/etc/hccn.conf 挂载进容器,然后在容器中使用 npu-smi info 命令查看容器中的卡号(每个容器挂载了 1 张卡),再根据卡号和/etc/hccn.conf 获取卡的 device_ip。由于容器中只有 1 张卡,device_logical_id 就是取 0。
通过上面的方法获取到 P 和 D 的 device 信息后,再添加到 rank_table 文件中,重新启动。重新启动后,有个新的报错”read ./conf/model_config/qwen2-b.json failed“,这个报错比较常见,把文件权限修改成 640 就可以了。再重新启动,可以看到 controller 中有日志”avaliable node 2“出现,同时可以看到 P 和 D 的日志中在加载模型,说明 P 和 D 创建成功了。
稍等一会可以看到 coordinator 的日志中出现”MindIE-MS coordinator is ready!!!“,说明 PD 分离服务部署成功了,这时候再用 curl 命令向 coordinator 节点发送推理请求,就可以得到回复了。
总结
需要清楚 controller、coordinator、P server 和 D server 节点的职责,再根据日志中的 error 信息和 fail 信息进行逐步分析。
评论