2、开发环境搭建:Docker环境配置、CUDA Toolkit安装、Triton编译器安装、昇腾CANN工具链安装、寒武纪Neuware安装
说实话,做跨芯片算子移植,最头疼的不是写代码,而是搭环境。
我见过太多人,代码写得挺漂亮,结果卡在环境配置上,一卡就是两三天。你想想看,不同芯片厂商的工具链、不同版本的依赖库、还有那些说不清道不明的系统兼容性问题……嗯,这章我们就来把这些坑一个个填平。
核心思路:用Docker做隔离,把不同芯片的开发环境装进不同的容器里。这样既不会污染宿主机,也能随时切换目标平台。
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% 做好了,后面写代码会顺畅很多。别急着写算子,先把环境搭稳。
嗯,这章的内容就这些。环境搭好了,下一章我们开始真正写算子——从最简单的向量加法开始,逐步深入到复杂的融合算子。
想要更多资料,联系可可