2、开发环境搭建:Docker环境配置、CUDA Toolkit安装、Triton编译器安装、昇腾CANN工具链安装、寒武纪Neuware安装

说实话,做跨芯片算子移植,最头疼的不是写代码,而是搭环境。

我见过太多人,代码写得挺漂亮,结果卡在环境配置上,一卡就是两三天。你想想看,不同芯片厂商的工具链、不同版本的依赖库、还有那些说不清道不明的系统兼容性问题……嗯,这章我们就来把这些坑一个个填平。

核心思路:用Docker做隔离,把不同芯片的开发环境装进不同的容器里。这样既不会污染宿主机,也能随时切换目标平台。

跨芯片算子移植 · 开发环境架构 Docker 容器 CUDA Toolkit Triton 编译器 昇腾 CANN 工具链 寒武纪 Neuware 宿主机只需安装 Docker 和 NVIDIA 驱动 各芯片工具链运行在独立容器中,互不干扰

2.1 Docker 环境配置

我个人习惯,所有开发环境都跑在 Docker 里。为什么?因为干净、可复现、好迁移。

你想想看,团队里五个人,每个人系统版本不一样,依赖库版本不一样,最后联调时各种「我这儿能跑啊」——这种痛苦我经历过太多次了。

我的建议:宿主机只装 Docker 和 NVIDIA 驱动(如果你用 GPU)。其他所有东西,都交给容器。

先装 Docker。Ubuntu 系统下,一行命令搞定:

curl -fsSL https://get.docker.com | bash -s docker

装完记得把当前用户加入 docker 组,不然每次都要 sudo:

sudo usermod -aG docker $USER
newgrp docker

然后装 NVIDIA Container Toolkit。这一步很多人会忘,结果容器里识别不到 GPU:

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker

注意:我曾经遇到过装了 nvidia-docker2 但容器里 nvidia-smi 报错的情况。后来发现是宿主机驱动版本太老,跟容器里的 CUDA 版本不匹配。所以建议宿主机驱动尽量保持最新。

2.2 CUDA Toolkit 安装

CUDA Toolkit 我建议用官方提供的 Docker 镜像,省心。比如:

docker pull nvidia/cuda:12.1.0-devel-ubuntu22.04

这里有个小细节:镜像标签里的 devel 表示开发版,包含了 nvcc 编译器、头文件和库文件。如果你只是跑推理,用 runtime 就行,但做算子开发必须用 devel。

启动容器时,记得加上 GPU 访问参数:

docker run -it --gpus all -v /path/to/your/code:/workspace nvidia/cuda:12.1.0-devel-ubuntu22.04 bash

进容器后,验证一下:

nvcc --version
nvidia-smi

看到版本号就说明环境通了。

避坑指南:我曾经在 CUDA 11.x 和 12.x 之间切换时,发现有些旧算子在新版本下编译不过。原因是 CUDA 12 去掉了某些 deprecated 的 API。所以建议你根据目标芯片的 SDK 要求,选择合适的 CUDA 版本,不要盲目追新。

2.3 Triton 编译器安装

Triton 是 OpenAI 出的一个 DSL,专门用来写 GPU 算子。它的安装方式比较灵活,我推荐用 pip 安装:

pip install triton

但要注意,Triton 对 Python 版本有要求。我踩过坑——Python 3.12 刚出来时,Triton 还没适配,装上去各种报错。所以建议用 Python 3.10 或 3.11。

如果你需要从源码编译(比如要修改 Triton 内部逻辑),可以这样:

git clone https://github.com/openai/triton.git
cd triton
pip install -e python/

编译过程会下载 LLVM 依赖,大概需要十几分钟。嗯,喝杯咖啡等一等就好。

验证安装:

python -c "import triton; print(triton.__version__)"

我的经验:Triton 的 nightly 版本更新很快,有时候会引入 breaking change。如果你在写生产环境的算子,建议锁定一个稳定版本,比如 2.1.0 或 2.2.0。

2.4 昇腾 CANN 工具链安装

昇腾的 CANN 工具链,说实话,安装过程比 CUDA 复杂一些。它不像 CUDA 那样有现成的 Docker 镜像,需要自己手动装。

首先,去昇腾官网下载 CANN 安装包。我一般下载 Ascend-cann-toolkit_xxx_linux-x86_64.run 这个文件。

安装命令:

chmod +x Ascend-cann-toolkit_*.run
./Ascend-cann-toolkit_*.run --install --install-path=/usr/local/Ascend

装完后,设置环境变量:

source /usr/local/Ascend/ascend-toolkit/set_env.sh

最好把这行加到 ~/.bashrc 里,免得每次都要手动 source。

验证安装:

npu-smi info

如果能看到 NPU 设备信息,就说明环境搭好了。

注意:昇腾的驱动和固件需要单独安装,CANN 只是工具链。我曾经犯过这个错——只装了 CANN,没装驱动,结果 npu-smi 一直报错。驱动可以从昇腾官网的「驱动与固件」页面下载。

2.5 寒武纪 Neuware 安装

寒武纪的 Neuware 安装相对简单。它提供了 deb 包和 pip 包两种方式。

我推荐用 deb 包安装,因为会同时安装驱动和运行时库:

sudo dpkg -i neuware*.deb

装完后,安装 Python 接口:

pip install neuware-mlu-ops

验证安装:

cnmon

这个命令类似于 NVIDIA 的 nvidia-smi,能看到 MLU 设备的状态。

我的建议:寒武纪的 Docker 镜像在 Docker Hub 上也能找到,比如 cambricon/neuware:latest。如果你不想污染宿主机,直接用 Docker 镜像是最省事的。

2.6 多环境统一管理

好了,现在你手上有了四个环境:CUDA、Triton、CANN、Neuware。怎么管理?

我的做法是写一个 docker-compose.yml,把每个环境定义成一个 service:

version: '3.8'
services:
  cuda-dev:
    image: nvidia/cuda:12.1.0-devel-ubuntu22.04
    runtime: nvidia
    volumes:
      - ./workspace:/workspace
    stdin_open: true
    tty: true

  ascend-dev:
    image: ascendhub.huawei.com/public/ascend-infer:latest
    volumes:
      - ./workspace:/workspace
    stdin_open: true
    tty: true

  cambricon-dev:
    image: cambricon/neuware:latest
    volumes:
      - ./workspace:/workspace
    stdin_open: true
    tty: true

这样,你只需要 docker-compose up -d 就能启动所有环境。切换时用 docker exec -it 进对应的容器就行。

核心要点:跨芯片算子移植,环境配置占了 30% 的工作量。把这 30% 做好了,后面写代码会顺畅很多。别急着写算子,先把环境搭稳。

嗯,这章的内容就这些。环境搭好了,下一章我们开始真正写算子——从最简单的向量加法开始,逐步深入到复杂的融合算子。

想要更多资料,联系可可