环境:华为昇腾910B × 8 | vLLM-Ascend v0.20.2rc1 | Docker
问题:同一台机器启动多个Docker容器运行TP并行推理时,HCCL通信端口冲突导致初始化失败

一、问题背景

在单台8卡昇腾910B服务器上,需要同时部署以下模型服务:

模型

用途

NPU卡

端口

TP数

BGE-M3

向量

0号

7007

1

Qwen3.6-27B-W8A8

视觉/短文本

0~3号

9009

4

Qwen3.6-27B-W8A8

长文本

4~7号

6006

4

其中视觉模型和长文本模型都使用了 tensor-parallel-size=4,即4卡张量并行。TP依赖HCCL(华为集合通信库,对标NCCL)在worker进程间建立通信组。

报错现象:

<span style="background-color:#e1e1e1">[ERROR] HCCL: Socket bind failed, address already in use

[ERROR] HCCL: Failed to create communicator</span>

二、问题根因

HCCL初始化时会分配Socket端口用于建立卡间通信连接。多个容器/进程同时启动TP推理时,如果HCCL分配的端口重叠,就会绑定冲突。

NVIDIA NCCL在多容器场景通常能自动避让端口冲突,但昇腾HCCL不支持自动端口分配,必须手动指定互不重叠的端口范围。


三、解决方案

3.1 核心环境变量:HCCL_NPU_SOCKET_PORT_RANGE

为每个需要HCCL通信的进程分配独立的、不重叠的端口区间:

# 容器1 - BGE-M3(单卡,无TP,但仍需预留端口)

HCCL_NPU_SOCKET_PORT_RANGE=16666-16676



# 容器1 - Qwen视觉模型(4卡TP)

HCCL_NPU_SOCKET_PORT_RANGE=16677-16687



# 容器2 - Qwen长文本模型(4卡TP)

HCCL_NPU_SOCKET_PORT_RANGE=16688-16698</span>

端口区间示意:

16666 ──── 16676  BGE-M3(单卡预留)

16677 ──── 16687  Qwen视觉模型(TP=4)

16688 ──── 16698  Qwen长文本模型(TP=4)

16699 ──── 16709  预留(如需第3个TP实例)</span>

3.2 NPU卡隔离:ASCEND_RT_VISIBLE_DEVICES

通过运行时环境变量限制每个进程可见的NPU设备(等价于NVIDIA的 CUDA_VISIBLE_DEVICES):

# BGE-M3:只用0号卡

ASCEND_RT_VISIBLE_DEVICES=0



# 视觉模型:用0~3号卡

ASCEND_RT_VISIBLE_DEVICES=0,1,2,3



# 长文本模型:用4~7号卡

ASCEND_RT_VISIBLE_DEVICES=4,5,6,7</span>

3.3 完整 docker-compose.yml

services:

  # 容器1:BGE-M3 + Qwen视觉模型(0~3号卡)

  model-emb-vl:

    image: quay.io/ascend/vllm-ascend:v0.20.2rc1

    restart: always

    privileged: true

    environment:

      HCCL_BUFFSIZE: "512"

      OMP_PROC_BIND: "false"

      OMP_NUM_THREADS: "1"

      TASK_QUEUE_ENABLE: "1"

      PYTORCH_NPU_ALLOC_CONF: "expandable_segments:True"

    ports:

      - "7007:7007"

      - "9009:9009"

    devices:

      - /dev/davinci0

      - /dev/davinci1

      - /dev/davinci2

      - /dev/davinci3

      - /dev/davinci4

      - /dev/davinci5

      - /dev/davinci6

      - /dev/davinci7

      - /dev/davinci_manager

      - /dev/devmm_svm

      - /dev/hisi_hdc

    volumes:

      - /usr/local/Ascend/driver:/usr/local/Ascend/driver:ro

      - /usr/local/dcmi:/usr/local/dcmi:ro

      - /usr/local/bin/npu-smi:/usr/local/bin/npu-smi:ro

      - /disk2/bge-m3:/models/bge-m3

      - /disk2/Qwen3.6-27B-w8a8:/models/Qwen3.6-27B-w8a8

    entrypoint:

      - /bin/bash

      - -lc

      - |

        # BGE-M3(单卡)

        HCCL_NPU_SOCKET_PORT_RANGE=16666-16676 \

        ASCEND_RT_VISIBLE_DEVICES=0 \

        vllm serve /models/bge-m3 \

          --served-model-name bge-m3 \

          --port 7007 --host 0.0.0.0 \

          --gpu-memory-utilization 0.1 \

          --max-model-len 8192 &



        # Qwen视觉模型(TP=4)

        HCCL_NPU_SOCKET_PORT_RANGE=16677-16687 \

        ASCEND_RT_VISIBLE_DEVICES=0,1,2,3 \

        VLLM_WORKER_MULTIPROC_METHOD=spawn \

        vllm serve /models/Qwen3.6-27B-w8a8 \

          --served-model-name qwen-vl \

          --port 9009 --host 0.0.0.0 \

          --tensor-parallel-size 4 \

          --quantization ascend \

          --max-model-len 25000 \

          --max-num-seqs 10 \

          --gpu-memory-utilization 0.85 \

          --trust-remote-code \

          --no-enable-prefix-caching &



        wait

    shm_size: 10.24gb

    ipc: host



  # 容器2:Qwen长文本模型(4~7号卡)

  model-text:

    image: quay.io/ascend/vllm-ascend:v0.20.2rc1

    restart: always

    privileged: true

    environment:

      HCCL_BUFFSIZE: "512"

      OMP_PROC_BIND: "false"

      OMP_NUM_THREADS: "1"

      TASK_QUEUE_ENABLE: "1"

      PYTORCH_NPU_ALLOC_CONF: "expandable_segments:True"

    ports:

      - "6006:6006"

    devices:

      - /dev/davinci0

      - /dev/davinci1

      - /dev/davinci2

      - /dev/davinci3

      - /dev/davinci4

      - /dev/davinci5

      - /dev/davinci6

      - /dev/davinci7

      - /dev/davinci_manager

      - /dev/devmm_svm

      - /dev/hisi_hdc

    volumes:

      - /usr/local/Ascend/driver:/usr/local/Ascend/driver:ro

      - /usr/local/dcmi:/usr/local/dcmi:ro

      - /usr/local/bin/npu-smi:/usr/local/bin/npu-smi:ro

      - /disk2/Qwen3.6-27B-w8a8:/models/Qwen3.6-27B-w8a8

    entrypoint:

      - /bin/bash

      - -lc

      - |

        HCCL_NPU_SOCKET_PORT_RANGE=16688-16698 \

        ASCEND_RT_VISIBLE_DEVICES=4,5,6,7 \

        vllm serve /models/Qwen3.6-27B-w8a8 \

          --served-model-name qwen-long \

          --port 6006 --host 0.0.0.0 \

          --tensor-parallel-size 4 \

          --quantization ascend \

          --max-model-len 100000 \

          --max-num-seqs 2 \

          --gpu-memory-utilization 0.90 \

          --trust-remote-code \

          --no-enable-prefix-caching

    shm_size: 10.24gb

    ipc: host</span>

四、关键配置说明

配置项

说明

HCCL_NPU_SOCKET_PORT_RANGE

最关键,每个TP进程组必须分配不重叠端口区间

ASCEND_RT_VISIBLE_DEVICES

运行时NPU卡隔离,等价于 CUDA_VISIBLE_DEVICES

ipc: host + shm_size: 10.24gb

TP多进程间共享内存通信,必须配置

VLLM_WORKER_MULTIPROC_METHOD=spawn

TP>1时vLLM多进程启动方式

HCCL_BUFFSIZE=512

HCCL通信缓冲区(MB),提升TP通信吞吐

devices 挂载全部davinci

驱动管理设备(manager/devmm_svm/hisi_hdc)必须全量挂载,实际卡隔离靠 ASCEND_RT_VISIBLE_DEVICES


五、排查命令

# 查看端口占用,确认各HCCL端口区间无重叠

ss -tlnp | grep -E '1666[0-9]|1667[0-9]|1668[0-9]|1669[0-9]'



# 查看NPU状态

npu-smi info



# 查看HCCL相关日志

docker logs <容器名> 2>&1 | grep -i hccl



# 查看NPU拓扑

npu-smi info -t topology</span>

六、总结

昇腾910B多容器并行部署的核心就一句话:HCCL_NPU_SOCKET_PORT_RANGE 必须为每个TP进程组分配不重叠的端口区间。这是昇腾与NVIDIA部署的最大差异——NCCL能自动避让,HCCL不行。

配合 ASCEND_RT_VISIBLE_DEVICES 做NPU卡隔离,即可稳定运行多容器多模型并行推理。


 

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐