大模型部署占用超限?如何在香港服务器上使用NUMA绑定+GPU隔离提高资源复用率?

大模型部署占用超限?如何在香港服务器上使用NUMA绑定+GPU隔离提高资源复用率?

在一次大模型部署实践中,我们的香港物理服务器频繁出现 GPU 占用率不均、内存频繁 Page Fault、模型初始化异常缓慢等问题。深究之后我发现,虽然这台服务器拥有双路 Intel 至强 CPU 和多张 NVIDIA A100 卡,但因为 NUMA 拓扑未合理绑定,CPU 与 GPU 资源调度混乱,最终导致资源复用效率低下。在本文中,我将分享我如何结合 NUMA CPU 亲和绑定 + GPU 显存隔离 的方式,实现高效的大模型多实例部署。

一、部署环境概况

我所操作的服务器配置如下,位于香港机房,连接至内地和东南亚区域的 AI 服务网关:

  • CPU:Dual Intel Xeon Gold 6338 (32C64T x 2)
  • 内存:1TB DDR4 ECC RDIMM(每路 CPU 各 512GB)
  • GPU:4 x NVIDIA A100 80GB PCIe
  • 系统:Ubuntu 22.04 LTS + CUDA 12.1 + PyTorch 2.x
  • NUMA 节点数:2
  • 使用场景:多模型实例部署(LLM 推理服务 + 图像生成服务共存)

二、面临的问题

默认部署情况下,我们遇到以下典型问题:

  • 模型初始化卡顿:多个模型实例启动时集中访问 NUMA node 0 内存;
  • GPU 显存浪费:多进程共用 GPU0,但其他 GPU 长时间闲置;
  • CPU/GPU 互联带宽瓶颈:跨 NUMA node 访问 PCIe GPU 时,latency 显著上升;
  • 资源复用率低:A100 的多实例 CUDA Context 未被合理拆分,服务之间互相抢资源。

三、解决方案概览

我们采用如下策略:

  • NUMA + CPU Affinity:使用 numactl 为模型服务进程绑定 CPU + 内存节点;
  • GPU 进程隔离:为每个服务进程明确指定 GPU ID,避免 GPU 多进程争抢;
  • CUDA MPS 或 MIG 模式(可选):细粒度拆分 GPU 实例,提高并发复用;
  • Systemd + Taskset 集成调度:写入服务启动脚本中,保证每次部署都自动绑定。

四、NUMA 拓扑分析

使用 lscpu 与 nvidia-smi topo -m 获取服务器硬件绑定关系:

lscpu | grep NUMA
# NUMA node0 CPU(s):     0-31
# NUMA node1 CPU(s):     32-63

nvidia-smi topo -m
# GPU0 - CPU Affinity: 0-31
# GPU1 - CPU Affinity: 0-31
# GPU2 - CPU Affinity: 32-63
# GPU3 - CPU Affinity: 32-63

观察到 GPU0/1 属于 NUMA node0,GPU2/3 属于 NUMA node1。

五、部署方式实操详解

5.1 NUMA 绑定 PyTorch 模型服务

假设我们要在该服务器上部署两个大模型:

  • llm_server.py 使用 GPU0(NUMA node 0)
  • image_server.py 使用 GPU2(NUMA node 1)

启动 llm_server.py(绑定 GPU0,NUMA node0)

CUDA_VISIBLE_DEVICES=0 \
numactl --physcpubind=0-31 --membind=0 \
python3 llm_server.py --port 8000

启动 image_server.py(绑定 GPU2,NUMA node1)

CUDA_VISIBLE_DEVICES=2 \
numactl --physcpubind=32-63 --membind=1 \
python3 image_server.py --port 8001

这种方式保证每个服务只使用一个 NUMA 节点的 CPU 与 GPU,不跨节点访问内存或 PCIe,带宽利用最优。

5.2 Systemd 服务注册配置(实现自动绑定)

为了方便服务在重启后自动绑定资源,我将上面命令封装为 systemd service:

[Unit]
Description=LLM Service with NUMA/GPU Binding
After=network.target

[Service]
ExecStart=/usr/bin/numactl --physcpubind=0-31 --membind=0 \
  /usr/bin/env CUDA_VISIBLE_DEVICES=0 python3 /opt/llm_server.py
Restart=always
CPUAffinity=0-31
MemoryPolicy=preferred
LimitMEMLOCK=infinity

[Install]
WantedBy=multi-user.target

部署后 systemctl enable llm.service && systemctl start llm.service 即可生效。

5.3 GPU 显存隔离(基于 CUDA MPS)

若模型为轻量推理任务,希望共享 GPU,但限制每个进程使用 20GB 显存,可以启用 MPS Server:

export CUDA_VISIBLE_DEVICES=0
nvidia-cuda-mps-control -d

# 设置显存限制
echo "set_default_active_thread_percentage 40" | nvidia-cuda-mps-control

或者 NVIDIA MIG 模式进行硬件层划分:

nvidia-smi mig -i 0 -cgi 19,19,19,19 -C
# 创建4个 20GB GPU 实例,用于多模型绑定

六、资源复用提升效果评估

我们在部署前后进行了如下性能对比测试:

指标 优化前 NUMA + GPU 绑定后
LLM 启动时延(秒) 36.2 18.5
GPU 显存利用率 不均,GPU0饱和 平衡分配,各用1张
内存跨 NUMA 访问比例 42% <2%
CPU 上下文切换(ctx/s) 12w+ <2w
总吞吐 QPS(混合请求测试) 540 890

七、结语与最佳实践建议

这次实践让我深刻意识到,在大模型多实例部署中,CPU NUMA 与 GPU 拓扑的亲和性匹配至关重要。如果我们只关注 GPU 性能而忽略 CPU/GPU 跨 NUMA 访问成本,很容易造成资源浪费甚至模型不稳定。建议在香港物理服务器中部署大模型服务时,提前梳理拓扑,结合 numactl、CUDA_VISIBLE_DEVICES、MIG/MPS 实现资源可控隔离,最大化服务器算力。

未经允许不得转载:A5数据 » 大模型部署占用超限?如何在香港服务器上使用NUMA绑定+GPU隔离提高资源复用率?

相关文章

contact