← 文章 / 芯片硬件
桑雅 10小时前 · 2026-09-06 09:26:50 · 4 阅读

我把 MiniMax-H3 装进了一张 Intel 显卡——A 卡 N 卡之外的第三条路,附零基础部署全流程

上一篇我在天台上一招 KO 了老板,用的是 5090。这回换个玩法:同一个模型,我把它搬到了一张 Intel 显卡上。

先说结论:能跑,画质一样,速度慢一截。 过程中我还把自己之前下的一个判断给推翻了。


一、先看片:15 秒,三个镜头,一次没剪

一段清晨的高山晨跑:远景是雪山和漫过山腰的云海,两个人沿着碎石小径并肩跑;跑着跑着,草丛边有只受伤的小狐狸;女生先蹲下伸手,男生随后半跪在她身后;最后她用外套把小狐狸裹进怀里,两人的手在衣角碰到一起,抬头对视,笑了。

这条片子是在一张 Intel Arc Pro B70 上生成的。 不是 Nvidia RTX 5090,是那张你在装机清单里基本不会考虑的 Intel 卡。

全部制作成本:

  • 三张参考图(两个人 + 一只狐狸的多视图定妆照)
  • 三段提示词(全文在第四节,一个字不藏)
  • 一张 Intel 显卡跑了 18 分钟

没有配音,没有音效后期。人物的对白、山间的风声、脚踩碎石的声音,都是模型自己"长"出来的。

三张图都是多视图定妆照:人物有面部特写 + 正面 / 侧面 / 背面全身,狐狸有四个角度的坐姿。给 H3 的参考图,视图越全,身份越稳——它要靠这些角度推断出人物在任意机位下该长什么样。


二、为什么要在 Intel 卡上折腾这件事

正常人不会这么干。买张 N 卡,pip install torch,完事。

但有两个现实理由:

第一,B70 有 32G 显存。 这是关键。跑视频模型,显存是第一道墙——你显存不够,再快的卡也跑不起来。同价位段里能给到 32G 的选择不多。

第二,N 卡不是永远买得到。 供货、价格、渠道,这两年大家都懂。多一条能走通的路,就多一份底气。

所以这次的问题很具体:CUDA 生态之外,这套东西到底能不能跑。

我先给出了一个错误答案

老实交代。我最开始的判断是 "跑不了",理由是:

H3 的量化格式叫 ConvRot INT8,负责解量化的库 comfy-kitchen 我去翻了它的安装包,里面只有两个编译好的内核文件:backends/cuda/ 和 backends/hip/(HIP 是 A 卡的)。没有 Intel 的

但我漏了一件事——那个库里还有一个叫 eager 的纯 PyTorch 后端,不依赖任何专用内核,能力清单里明明白白列着 dequantize_int8_convrot_weight。跑在 Intel 卡上时,它会自动选中这个后端。

教训:查能力,别数文件。 判断一个库支不支持某个硬件,去问它的能力注册表(registry.list_backends()),别靠数编译产物。有没有专用内核决定的是快慢,不是能不能


三、部署:从零开始,六步

先摆机器:

部件配置
显卡Intel Arc Pro B70,32G 显存(实测可用 30.3 GiB)
内存96G
系统Debian 13 (trixie),内核 7.0(跑在 Proxmox 虚拟机里)
磁盘给模型留 60G 以上

第 0 步:确认驱动装好了

Intel 卡跑计算,靠两套东西:内核驱动xe,新一代 Intel 显卡驱动,内核自带)和用户态运行时(Level Zero + OpenCL)。

# 看内核驱动加载没
lsmod | grep xe

# 看运行时装没装
clinfo | grep "Device Name"

正常应该能看到你的卡名。运行时包是这三个:

apt install intel-opencl-icd libze-intel-gpu1 libze1

我这台的版本是 26.22.38646.4(Intel 计算运行时)+ libze1 1.31.0版本别太老,B 系列(Battlemage)显卡需要较新的运行时才认得。

第 1 步:Python 环境

Debian 13 自带 Python 3.13。装 venv 的时候有个小坑:

apt-get update          # ← 这句别省,包索引过期会 404
apt-get install -y python3.13-venv
python3 -m venv /root/comfy-xpu

踩坑记录:我直接 apt install python3.13-venv 报了 404,因为本地包索引是旧的,指向的版本号已经被新版替换了。apt-get update 一下就好。

第 2 步:装 XPU 版 PyTorch ← 最关键的一步

Intel 卡在 PyTorch 里叫 XPU(对应 N 卡的 CUDA)。装的是专门的构建版本:

/root/comfy-xpu/bin/pip install torch torchvision torchaudio \
    --index-url https://download.pytorch.org/whl/xpu

装完验一下:

python -c "import torch; print(torch.__version__, torch.xpu.is_available())"
# 2.13.0+xpu True

看到 True 就成了。这一步通了,后面基本就是常规操作。

第 3 步:装 ComfyUI 和依赖 ← 这里有个大坑

git clone https://github.com/comfyanonymous/ComfyUI.git /root/ComfyUI

我用的是 ComfyUI 0.30.0。H3 的节点是 core 内置的,不用装自定义节点包(另外有个 ComfyUI-MiniMax-H3-Guide 节点包提供提示词辅助,可选)。

然后是那个大坑。 直接 pip install -r requirements.txt 会毁掉你刚装好的 XPU PyTorch

原因:requirements 里的 torchsde 和 spandrel 声明依赖 torch>=1.6.0。pip 一看这个泛型要求,转头就去 PyPI 拉了CUDA 版的 torch,把你的 XPU 版覆盖掉。我当时是看到日志里开始下载 nvidia-cudnn-cu13 才发现不对,赶紧掐了。

正确做法是用 constraints 文件把 torch 钉死

# 先把已装版本钉下来
cat > /root/pin_torch.txt <<EOF
torch==2.13.0+xpu
torchvision==0.28.0+xpu
torchaudio==2.11.0+xpu
EOF

# 装依赖时带上 -c,并排除三个 torch 包
grep -viE "^torch$|^torchvision|^torchaudio" requirements.txt > reqs_notorch.txt
pip install -r reqs_notorch.txt -c /root/pin_torch.txt \
    --extra-index-url https://download.pytorch.org/whl/xpu

⚠️ 注意 torchsde 要保留——它是 ComfyUI 真正的依赖(采样器要用),不是 PyTorch 本体。我第一次过滤的时候连它一起删了,是错的。过滤条件要写精确:^torch$ 只匹配 torch 本身。

装完再验一次 torch.xpu.is_available(),确认还是 True

第 4 步:下模型权重

四个文件,总共 50.22 GiB

组件文件大小放哪
扩散模型minimax_h3_ref2va_pruned_int8_convrot19.53 GiBmodels/diffusion_models/
文本编码器qwen3vl_32b_minimax_h3_int8_convrot25.28 GiBmodels/text_encoders/
视频 VAEminimax_h3_video_vae_fp164.85 GiBmodels/vae/
音频 VAEminimax_h3_audio_vae_fp320.56 GiBmodels/vae/

从 HuggingFace 的 Comfy-Org/MiniMax-H3 拉。建议开 hf_transfer(多线程下载),我这边实测能跑到 32 MB/s

pip install hf_transfer
HF_HUB_ENABLE_HF_TRANSFER=1 hf download Comfy-Org/MiniMax-H3 --local-dir ...

注意那个 pruned(剪枝版):19.5G 而不是完整版的 31.7G。H3 有约 13B 参数在 AdaLN 分支上,推理时根本用不到,剪掉不影响画质——这也是官方模板的默认选择,不是什么降级方案。

第 5 步:起服务

cd /root/ComfyUI && /root/comfy-xpu/bin/python main.py --listen 0.0.0.0 --port 8188

启动日志里认准这两行:

Total VRAM 32656 MB, total RAM 98304 MB
Device: xpu:0 Intel(R) Arc(TM) Pro B70 Graphics

看到 Device: xpu:0 就对了。想让它开机自启,写个 systemd 单元即可。


四、显存账和速度账:真实数字

显存:50G 的模型怎么塞进 32G 的卡

答案是不塞——ComfyUI 按阶段把模块换进换出,显卡上永远只放当前干活的那一个。这是从 ComfyUI 日志里抠出来的真实记录:

阶段显存占用
文本编码器工作时25,884 MB
换出编码器、换入扩散模型释放 22,899 MB → 装入 19,996 MB
视频 VAE 解码4,966 MB
音频 VAE 解码577 MB

峰值是文本编码那一段的 约 25.9 GB,30.3 GiB 的可用显存扛得住,但余量不算宽裕。

所以大内存是隐形前提。 换出去的模块要放系统内存里,96G 内存在这套配置里不是奢侈,是必需。显存不够内存凑——这个思路我在讲大语言模型那两篇里说过,视频模型上照样成立。

速度:慢,但可用

任务耗时
608×352 / 39 帧 / 6 步(冒烟测试)75 秒
864×480 / 124 帧 / 20 步(5.17 秒成片)约 360 秒
本文这条 15 秒片(三镜)约 18 分钟

对比一下:同样是 r2v、同样 20 步,5090 上 5 秒片实测 98.9 秒B70 慢了大约 3.6 倍。

慢在哪?就慢在第二节说的那个 eager 后端——没有专用内核,走的是纯 PyTorch 回退路径。这不是 Intel 卡本身算力的问题,是生态的问题:量化内核目前只为 CUDA 和 HIP 编译。

这个速度能接受吗? 看你干什么:

  • 快速刷 seed 抽卡——别用,太慢,一晚上刷不了几条。
  • 批量出片、隔夜跑——完全可用。三条 5 秒片 18 分钟,一晚上能出几十条。
  • 给一台闲置的 Intel 机器找活干——很划算,它跟主力 N 卡机器并行跑,互不抢资源。

五、提示词全文(三镜)

用的是 H3 的 六段式 Ref2VA 格式——参考图定"是谁",提示词定"演什么"。这套格式我在上一篇拆过,这里只贴实际用的,格式细节看上一篇第三节。

三镜共用的角色定义(每镜只写该镜真正出现的角色,这点很重要,下面会说为什么):

subject_definitions:
 (来自参考图 1,男性角色):光头、戴细框深色眼镜、留短髭须的中年亚洲男性,
面部轮廓清晰,笑起来眼角有细纹。本片中他穿深灰色长袖跑步上衣与黑色运动长裤、灰白色跑鞋。
 (来自参考图 2,女性角色):短卷发、圆脸、皮肤白皙的亚洲女性,神情温和。
本片中她穿米白色跑步上衣与深灰色紧身运动裤、浅色跑鞋。
 (来自参考图 3,一只红狐狸):橙红色皮毛、白色胸腹与颊部、四肢末端与耳尖为黑色、
尾巴蓬松且尾尖白色,体型偏小,是一只幼年狐狸。本片中它左前腿受伤,行动迟缓。
 (场景):清晨的高山草甸,远处是连绵的雪山与流动的云海,
中景是开满淡紫色野花的草坡,一条碎石小径蜿蜒穿过。
说话人 (S1) 为 ,中年男声,音色偏低、语速平缓。
说话人 (S2) 为 ,女声,音色清亮柔和。

第一镜(山径 · 只有两个人,没有狐狸):

summary:
[reference generation] 本任务参考 、 的人物外观与  的场景设定,
生成一段清晨山间晨跑的写实电影镜头。本镜头中只有这两个人物,画面里没有任何动物。

detailed_description:
[Shot 1] 真实电影摄影,35mm 胶片质感,清晨柔和的金色侧逆光穿过山谷晨雾,色调温暖治愈,浅景深。
开场为大远景航拍构图:画面上三分之二是连绵的雪山群峰,峰顶被朝阳染成暖金色,
山腰缠绕着缓慢流动的乳白色云海;画面下三分之一是开满淡紫色野花的高山草甸,
一条浅色碎石小径从画面右下方蜿蜒伸向远处山脚。
 与  并肩沿小径向远处慢跑,在辽阔的山景中只占画面很小的比例,
两人步伐轻松同步,手臂自然摆动,跑步时肩背有轻微起伏。
小径上除了这两个人以外空无一物,草甸与山径上没有任何动物出现。
野花与草叶在晨风中持续摇曳,云海在远山间缓慢漂移,光线随云影在草坡上缓慢移动。
跑动中  微微侧头看向身旁的 ,语气轻快地说
(S2) [Chinese] 你看那边,云都在山腰上飘。
 顺着她的目光望向远山,微笑着回应
(S1) [Chinese] 值了,早起这一趟真值了。
The camera trucks right with large amplitude at slow speed while slowly pedestals down,
revealing the full breadth of the mountain range.

overall_soundscape:
Gentle alpine wind moving through tall grass, distant birdsong at dawn,
the rhythmic crunch of running shoes on loose gravel, light breathing and the rustle of technical fabric.

non_diegetic_music:
N/A

第二镜(发现 · 三个角色都在):

detailed_description:
[Shot 1] 真实电影摄影,35mm 胶片质感,清晨柔和的金色侧逆光,暖调,浅景深。
中景构图:画面左侧是碎石小径边缘的草丛,右后方虚化的背景里是被晨光照亮的雪山轮廓。
 蜷缩在小径旁的草地上,橙红色皮毛在逆光中透出绒毛边缘光,
左前腿姿态不自然地蜷着,耳朵警觉地立起又放平,湿润的眼睛看向来人,身体因不安而轻微发抖。
 从画面右侧跑入,看到小狐狸后立刻放慢并停下,随即缓缓蹲下身,
上半身前倾,右手掌心向上非常缓慢地朝小狐狸伸出,动作轻柔克制,脸上是关切与怜惜的神情。
 随后跑入停在她身后半步,看清情况后也单膝跪下,身体微微前倾,
目光落在小狐狸受伤的前腿上,眉头轻皱。
 一边伸手一边压低声音说 (S2) [Chinese] 别怕,别怕,我们不伤害你。
 看清伤处后低声开口 (S1) [Chinese] 它前腿受伤了,我们得带它下山。
两人都刻意放轻声音,避免惊吓到小动物。草叶在他们身边轻微晃动。
The camera pushes in with small amplitude at slow speed toward the fox,
the background mountains softening into bokeh.

第三镜(对视 · 情感落点):

detailed_description:
[Shot 1] 真实电影摄影,35mm 胶片质感,清晨温暖的金色阳光,浅景深,治愈的暖色调。
近景构图,两人并排蹲在碎石小径上,背景是虚化的雪山与流动云海。
 双手捧着一件浅色薄外套,动作极轻地把  裹住抱起,
小狐狸起初还在轻微挣动,被裹住后逐渐安静下来,把下巴搭在她的小臂上,耳朵放平,
尾巴垂在外套外侧轻轻摆了一下。
 蹲在她右侧,伸出右手替她把滑落的外套边角向上掖好,
两人的手背在外套边缘短暂相触,两人同时微微一顿,抬起头对视,
 先露出温柔的笑意, 也回以微笑,随即两人都有些不好意思地移开视线,
 低头看向怀里的小狐狸,轻声说 (S2) [Chinese] 它好像不抖了。
 看着她,语气温和地接道 (S1) [Chinese] 那我们慢点走,我陪你一起。
 抬眼看他,笑着点了点头。晨风吹动她额前的碎发。
The camera pulls out with small amplitude at slow speed while pedestaling up,
framing the two of them kneeling together on the trail with the sunlit snow peaks behind.

为什么分三段,而不是一条 15 秒

H3 单次生成的上限是 362 帧 ≈ 15.08 秒,所以一条到底技术上做得到。

一次生成 = 一个连续镜头,中间没有剪辑点。这个故事有"远景 → 发现 → 对视"的推进,三段需要不同的景别和镜头运动(横移下降 / 缓推 / 拉远升起),一镜到底做不了这种切换。

还有个实际好处:分段能单独重跑。 362 帧一次成片,第 300 帧崩了整条白跑 18 分钟;分三段,重跑一镜也是 6 分钟。这一点在下面立刻就用上了。

一个真实的翻车和它的修法

第一版跑出来,第一镜里小狐狸跟着两个人一起跑——故事还没到"偶遇",狐狸提前出场了。

奇怪的是,那一镜我只喂了两张人物参考图,根本没喂狐狸图。

原因在提示词里:我三个镜头共用了同一份 subject_definitions,里面定义了 <Subject 3> 是只受伤的狐狸;retention_analysis 里还写着"<Subject 3> 出现在 [Shot 1]"。我等于亲口告诉模型:这一镜里有只狐狸。 它照做了。

修法很直白——每一镜只定义该镜真正出现的角色:第一镜的定义里删掉狐狸,场景顺延成 <Subject 3>retention_analysis 同步改,overall_soundscape 里那句"细微的动物呜咽声"也一并删掉,再补一句"小径上除了这两个人以外空无一物"。重跑那一镜,6 分钟,狐狸没了。

要领:subject_definitions 不是角色表,是"本镜出场表"。 你定义了什么,模型就倾向于画什么——哪怕你没给对应的参考图。多镜头项目里,这个块要按镜裁剪,不能图省事全片共用。


六、几条带走的认识

Intel 卡跑得动这类模型,但生态差距是真的。 能跑,画质没有任何劣化,代价是 3.6 倍的速度。这个差距不在硬件算力,在量化内核只为 CUDA/HIP 编译。等生态补齐,这个差距会缩小;在那之前,Intel 卡适合当"隔夜批量出片"的第二台机器,不适合当交互式抽卡的主力。

判断"支不支持",要查能力不要数文件。 我差点因为安装包里没有 Intel 内核就否掉整件事,实际上纯 PyTorch 的回退后端跑得好好的。没有专用内核决定的是快慢,不是能不能。

装 XPU PyTorch 最大的敌人是 pip 自己。 任何一个声明 torch>=x 的普通依赖,都可能让 pip 把你的 XPU 版换成 CUDA 版,而且装完不报错——直到你发现 torch.xpu.is_available() 变成了 False。用 constraints 钉死,装完复验。

提示词里"多说的话"和"说错的话"一样有害。 那只提前出场的狐狸,不是模型不听话,是我在角色定义里明明白白写了它。生成模型不会替你判断哪些信息是"背景资料"、哪些是"本镜要画的"——你写进去的,它就当成要画的。


我是把视频模型装进 Intel 显卡、然后发现狐狸提前出场了的桑雅。想我了就常来。

原始来源: 桑雅

评论 (0)