拿到一张或多张 Intel D270 加速卡之后,真正要解决的问题不是"插上去能不能亮",而是三件事:驱动栈能不能把卡认出来、PyTorch 与 llama.cpp 能不能把计算真正卸载到卡上、多卡聚合出来的大显存容量能不能被框架当成一整块来用。这篇教程按顺序把这三件事走一遍,每一步都给出可复制的命令和判断成功的方法。
本文不写具体版本号和下载链接,凡是涉及版本、包名、镜像地址的地方,一律以官方文档当前版本为准;文中出现的命令都是通用写法,具体参数含义用 --help 确认。
适用场景
适合已经拿到 D270 加速卡、准备在 Linux 服务器上跑本地大模型的开发者和运维。典型场景有两类:一是把单机多卡聚合成一块总量约 480GB 的可用显存,用来加载参数量大、上下文长的模型;二是把原本跑在 CPU 或消费级卡上的推理服务迁到这台机器上,需要对比迁移前后的吞吐。如果你的目标是跑 7B 级别的小模型,这套流程略显重,可以跳过显存池部分。
环境与前置条件
操作系统建议使用主流企业级 Linux 发行版(如 Ubuntu LTS 或 RHEL 系),内核版本需要包含对应代次的 Intel GPU 内核驱动模块(i915 或较新的 xe),具体最低内核版本以官方文档当前版本为准。发行版自带的旧内核经常不满足要求,升级内核是常见的第一步。
运行时与软件栈:
- Intel oneAPI Base Toolkit(提供
icx/icpx编译器和 SYCL 运行时) - Level Zero 加载器与 GPU 驱动
- Intel XPU 版本的 PyTorch(CPU 版 PyTorch 不会识别加速卡)
- llama.cpp(编译时开启 SYCL 后端)
硬件与资源建议:
- 内存:不小于单卡显存总量的一半,大模型加载时有明显的 CPU 侧缓冲
- 磁盘:预留模型文件体积的两倍以上,加载与转换 GGUF 都会临时占空间
- 供电与散热:多卡机器要确认机箱风道和电源余量,加速卡降频往往先从散热开始
- BIOS:开启 Above 4G Decoding、Resizable BAR 和 IOMMU(虚拟化环境必须)
安装系统级驱动通常需要 root,后续编译和跑模型用普通用户即可,但要保证该用户在 render 和 video 组里。
分步骤部署
第一步:确认 BIOS 与系统层面已经"看见"卡
先不装任何软件,从最底层确认硬件在位:
```bash
lspci -nn | grep -i -E 'vga|display|3d|processing'
```
预期能看到 Intel 的加速设备条目。如果一条都看不到,问题在 PCIe 插槽、供电或 BIOS,不用继续往下走。同时确认 IOMMU 已开启:
```bash
dmesg | grep -i -E 'DMAR|IOMMU'
```
如果没有相关输出,需要在 BIOS 中打开 VT-d / IOMMU,并在内核启动参数里加上 intel_iommu=on iommu=pt(具体写法参考发行版文档),改完重启。
第二步:安装内核驱动与 Level Zero 驱动栈
按照 Intel 官方文档添加对应的软件仓库,然后安装 GPU 驱动、Level Zero 加载器和命令行工具。常见包名类似:
```bash
sudo apt update
sudo apt install -y intel-gpu-tools level-zero intel-level-zero-gpu
```
这一步在做什么:intel-gpu-tools 提供 intel_gpu_top 这类底层观测工具,Level Zero 是上层框架(PyTorch、llama.cpp)访问 Intel GPU 的通用接口。装完之后 /dev/dri 下应该会出现 card0、renderD128 之类的设备节点:
```bash
ls -l /dev/dri
groups $USER
```
如果当前用户不在 render 组,执行 sudo usermod -aG render,video $USER 后重新登录。
第三步:安装 oneAPI 并初始化环境
从官方渠道安装 oneAPI Base Toolkit 后,每个新开的 shell 都要先初始化环境:
```bash
source /opt/intel/oneapi/setvars.sh
```
判断成功的方法:which icpx 能返回编译器路径,echo $ONEAPI_ROOT 有输出。这一步没做的话,后面 llama.cpp 编译会直接报找不到编译器。
第四步:验证设备可见性
```bash
sycl-ls
```
正常输出里会列出 [level_zero:gpu] 开头的设备。如果一块卡在物理上被拆成多个 tile / 子设备,默认可能只暴露一个逻辑设备,需要设置:
```bash
export ZE_FLAT_DEVICE_HIERARCHY=FLAT
sycl-ls
```
FLAT 模式下每个子设备单独列出,写并行程序时更直观;COMPOSITE 模式下则把同一张卡的多个 tile 合成一个设备。两种模式对显存统计和模型切分的影响不同,先确定你要用哪种,再往下走。
配套再确认一遍硬件信息和实时占用:
```bash
xpu-smi discovery
sudo intel_gpu_top
```
xpu-smi discovery 会把每张卡的编号、显存容量、驱动版本列出来,这是后面计算显存池总量的依据。intel_gpu_top 是交互式的,按 q 退出。
第五步:安装 XPU 版 PyTorch 并做张量搬运测试
按官方指引安装支持 XPU 的 PyTorch(安装命令随版本变化,以官方文档当前版本为准)。装完之后做最小验证:
```bash
python - <<'PY'
import torch
print("xpu available:", torch.xpu.is_available())
print("device count:", torch.xpu.device_count())
if torch.xpu.is_available():
for i in range(torch.xpu.device_count()):
print(i, torch.xpu.get_device_properties(i))
a = torch.randn(4096, 4096, device="xpu")
b = torch.randn(4096, 4096, device="xpu")
c = a @ b
torch.xpu.synchronize()
print("matmul ok:", c.shape, c.dtype)
PY
```
xpu available: True 且矩阵乘法不报错,说明 PyTorch 这条链路通了。如果 device_count 是 0,说明装的还是 CPU 版或者驱动栈没被识别,回到第四步排查。
第六步:编译 llama.cpp 的 SYCL 后端
```bash
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
source /opt/intel/oneapi/setvars.sh
cmake -B build \
-DGGML_SYCL=ON \
-DCMAKE_C_COMPILER=icx \
-DCMAKE_CXX_COMPILER=icpx \
-DGGML_SYCL_F16=ON
cmake --build build --config Release -j $(nproc)
```
GGML_SYCL_F16=ON 打开半精度算子路径,在支持 FP16 的卡上通常更快。编译结束后 build/bin/ 下会出现 llama-cli、llama-server、llama-bench。成功标志是编译过程中能看到 SYCL 相关的后端被编进去,而不是只有 CPU 后端。
第七步:单卡加载模型并跑通推理
准备一个 GGUF 格式的模型文件,先用一张卡试:
```bash
ONEAPI_DEVICE_SELECTOR=level_zero:0 \
./build/bin/llama-cli \
-m /path/to/model.gguf \
-ngl 99 \
-c 8192 \
-p "用一句话解释什么是张量并行。"
```
-ngl 99 表示把尽可能多的层卸载到 GPU。成功的话会看到模型加载日志里出现 SYCL 后端信息,随后正常输出文字。如果日志显示大部分层还在 CPU 上,说明卸载没生效或者显存不够。
第八步:启用多卡显存池
这一步是"480GB 显存池"能否兑现的关键。先确认框架侧看到几张设备,再让模型按层切分到多张卡上:
```bash
ONEAPI_DEVICE_SELECTOR=level_zero:* \
./build/bin/llama-cli \
-m /path/to/model.gguf \
-ngl 99 \
--split-mode layer \
-ts 1,1,1,1 \
-c 32768
```
-ts 1,1,1,1 表示四张卡按等比例切分,卡数与实际硬件对应。判断成功的方法是:加载日志里每一层分配到哪张设备都有记录,且推理过程中用 xpu-smi 或 intel_gpu_top 观察,多张卡的占用同时上升,而不是一张忙其余空闲。
需要说明的是,把多卡"聚合成一块 480GB 显存"有两种含义:一种是总量意义上的聚合,即模型被切到多卡上、对外表现为一个可加载大模型的服务,这是当前框架普遍支持的方式;另一种是硬件级的统一地址空间与卡间对等访问,是否支持、需要什么拓扑(比如专用互联链路)取决于卡型和主板,具体以官方文档当前版本为准。如果卡间只能走 PCIe 且没有对等访问,跨卡通信会成为瓶颈,这时优先考虑张量并行度低一些、层切分多一些的配置。
第九步:测吞吐
用自带的 benchmark 工具做可复现的测量:
```bash
ONEAPI_DEVICE_SELECTOR=level_zero:* \
./build/bin/llama-bench \
-m /path/to/model.gguf \
-ngl 99 \
-p 512 -n 128 \
-r 3
```
-p 是预填充长度,-n 是生成 token 数,-r 是重复轮数。输出会给 pp512(预填充吞吐)和 tg128(生成吞吐)两个指标。建议至少对比三组:单卡 vs 多卡、不同上下文长度、不同量化精度。同一台机器上多次测量取中位数,避免把首次加载的冷启动时间算进去。
对外提供 OpenAI 兼容接口时改用 llama-server:
```bash
ONEAPI_DEVICE_SELECTOR=level_zero:* \
./build/bin/llama-server \
-m /path/to/model.gguf \
-ngl 99 --split-mode layer -ts 1,1,1,1 \
-c 32768 --host 0.0.0.0 --port 8080
```
验证部署是否成功
按下面四条逐项确认,全过就说明链路完整:
1. sycl-ls 输出中包含 [level_zero:gpu] 设备,数量与物理卡/子设备数量一致。
2. xpu-smi discovery 能列出每张卡的显存容量,累加后接近预期的池化总量。
3. PyTorch 脚本打印 xpu available: True,device_count 与卡数一致,且大矩阵乘法能跑完不报错。
4. llama-bench 能正常输出 pp 与 tg 指标,并且测量过程中多张卡的利用率同时非零。
再补一个稳定性验证:把上下文长度设成你实际要用的值(例如 32768),连续跑一段时间的长文本生成,观察是否出现掉卡、超时或显存缓慢增长。这一步比跑分更能暴露问题。
常见报错与解决
报错信息:sycl-ls 只列出 [opencl:cpu] 或 [host:cpu],没有 GPU 设备。
原因:GPU 驱动或 Level Zero 驱动未加载,或者当前用户没有 render 设备权限。
解决:
```bash
ls -l /dev/dri
sudo usermod -aG render,video $USER
重新登录后
source /opt/intel/oneapi/setvars.sh && sycl-ls
```
报错信息:libze_loader.so.1: cannot open shared object file: No such file or directory。
原因:Level Zero 加载器未安装,或者新 shell 没有初始化 oneAPI 环境变量。
解决:
```bash
sudo apt install -y level-zero
source /opt/intel/oneapi/setvars.sh
ldconfig -p | grep libze_loader
```
报错信息:PyTorch 报 RuntimeError: Found no NVIDIA driver 或 torch.xpu.is_available() 返回 False。
原因:装的是 CPU 版或 CUDA 版 PyTorch,不是 XPU 版。
解决:卸载后按官方 XPU 安装指引重装,装完复验:
```bash
pip uninstall -y torch torchvision torchaudio
按官方文档当前版本给出的 XPU 安装命令重装
python -c "import torch; print(torch.xpu.is_available())"
```
报错信息:llama.cpp 编译时报 icx: command not found 或 CMAKE_C_COMPILER not found。
原因:编译前没有 source setvars.sh,或者 oneAPI 未安装。
解决:
```bash
source /opt/intel/oneapi/setvars.sh
which icx icpx
rm -rf build && cmake -B build -DGGML_SYCL=ON -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx
```
报错信息:模型加载到一半报显存不足,或者 ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY。
原因:单卡放不下当前上下文长度和 batch,或没有启用多卡切分。
解决:降低上下文(-c)、提高切分比例,或显式指定多卡:
```bash
ONEAPI_DEVICE_SELECTOR=level_zero:* ./build/bin/llama-cli -m model.gguf -ngl 99 --split-mode layer -ts 1,1,1,1 -c 16384
```
报错信息:多卡机器上只有一张卡在跑,其余空闲。
原因:设备选择器限制在单卡,或者未传 -ts、--split-mode。
解决:
```bash
echo $ONEAPI_DEVICE_SELECTOR # 确认是 level_zero:* 而不是 level_zero:0
ONEAPI_DEVICE_SELECTOR=level_zero:* ./build/bin/llama-cli -m model.gguf -ngl 99 --split-mode layer -ts 1,1,1,1
```
若设置后仍未生效,检查 ZE_FLAT_DEVICE_HIERARCHY 是否与你的切分策略匹配。
后续维护
环境固化:oneAPI 与驱动版本升级后,PyTorch 和 llama.cpp 都需要重新验证。建议把驱动版本、oneAPI 版本、框架 commit 记录在案,升级前先在一台机器上灰度。不要把 source setvars.sh 写进全局 profile,多版本共存时容易互相覆盖。
备份:需要备份的是环境配置而不是驱动二进制——内核启动参数、BIOS 选项、/etc/modprobe.d 下的相关配置、conda/venv 的依赖清单、llama.cpp 的编译参数。模型文件单独存放,做好校验和。
升级路径:驱动 → oneAPI → 框架,按这个顺序升。每升一级跑一遍上文的四条验证。内核升级后如果卡消失,优先怀疑驱动模块与新内核不匹配。
日志与监控:日常巡检用 xpu-smi discovery 看设备是否在线,用 intel_gpu_top 或 xpu-smi 的采样功能看利用率和显存占用趋势。推理服务要记录首 token 延迟、生成吞吐和显存峰值,这三项能提前反映显存泄漏和跨卡通信瓶颈。建议给每张卡设置利用率与温度的告警阈值,多卡机器上一张卡降频会拖慢整个张量并行组。
性能调优顺序:先确认设备全部在线,再调上下文长度与 batch,最后才动切分比例。跨卡通信成本高的拓扑下,减少张量并行度、增加层切分通常更划算;具体怎么选,用 llama-bench 在目标模型上实测一轮,比套用别人的参数更可靠。
