LTX-2.3 本地部署完整复盘

先把结论放前面:LTX-2.3(22B)这条 pipeline 在 4×RTX 3090(24GB)这套硬件上,按官方默认推理方式基本跑不起来。我最终得到的不是“没跑通”,而是一个更有价值的结果:把它为什么跑不起来、卡在哪、该怎么判断“物理不可行”,完整验证了一遍。

这篇文章是一次本地部署的工程复盘:从模型文件下载、依赖链补齐、环境和代码层踩坑,到显存拆分、多卡 device 规划,再到最终 OOM 的边界判断。希望你在遇到类似“看起来只要把权重放进去就能跑”的大模型工程时,可以少走很多弯路。


TL;DR(1 分钟读完)

  • LTX-2.3 不是单模型,而是一个多组件 pipeline:文本编码器(Gemma)+ 视频 diffusion 主模型(22B)+ 可能的增强/上采样等。
  • 仅下载 ltx-2.3-22b-distilled.safetensors(≈46GB)并不够,运行时会继续依赖 HuggingFace 生态的一整套配置文件与子模型。
  • 我在 3090 上遇到两类 OOM:
    • Gemma(12B)加载阶段先爆一次(prompt encoder 直接吃掉接近一张 3090 的可用显存)。
    • diffusion 主模型推理阶段仍然爆(不是调小分辨率/帧数就能解决的那种)。
  • 做到“能跑”的三条现实路线:
    1. CPU / NVMe offload(能出结果但会很慢);
    2. 真正意义上的模型并行/张量并行(需要改造实现,不是简单多卡);
    3. 换更现实的模型/蒸馏版本。

1. 背景

目标很直接:

  • 在本地 GPU 服务器上部署 LTX-2.3(22B)视频生成模型
  • 硬件:4×RTX 3090(每张 24GB)
  • 系统:Ubuntu 24.04
  • 网络受限:需要手工下载模型(避免 git-lfs 拉爆、断点续传等)

我以为这会是一件“把权重下载下来、装依赖、跑脚本”的事。事实证明:当模型规模跨过某个阈值后,部署问题本质上会从“软件配置”变成“系统工程 + 资源规划”。


2. 一个关键认知:LTX 是 pipeline,不是“一个模型”

很多部署失败,是从最初的心理模型就错了。

LTX-2.3 的推理链路更像这样:

Prompt(文本)
  ↓
Text Encoder(Gemma)
  ↓
Diffusion 主模型(视频生成)
  ↓
(可选) Upsampler / Enhancer
  ↓
Video Output

也就是说你不是在部署一个 .safetensors,而是在部署一条 由多个模型 + 多套配置 + 多段推理代码组成的 pipeline。

只要这条链上的任何一环缺文件、缺 config、版本不匹配,你就会看到“看似随机”的报错。


3. 第一步:下载主权重,但很快发现“这只是开始”

我先手工下载了 diffusion 主模型的权重:

ltx-2.3-22b-distilled.safetensors  ≈ 46GB

这一步本身没什么技术含量,但它会带来一个误导:你会以为“权重有了就能跑”。

很快,运行就报错(典型的第一类缺失):

找不到 preprocessor_config.json

这意味着:代码实际上在按 HuggingFace 的模型目录结构去找东西——不仅是权重文件,还包括 tokenizer / processor / config 这一整套元数据。


4. 最大的坑:Gemma 依赖与版本匹配

继续顺着报错和代码路径往下挖,我定位到:

PromptEncoder → GemmaTextEncoder

结论很明确:必须提供 Gemma 模型。并且不是“随便一个 Gemma”。

我走了三次典型的错误分支:

4.1 gemma-2:架构不匹配

这类错误的特征是:你能加载一部分,然后在模型结构对齐/层数/命名上出现不兼容。

4.2 gemma-3-4b:尺寸不匹配

报错类似:

hidden_size mismatch(2560 vs 3840)

这基本可以断定:上游代码/权重期望的是更大规格的文本编码器。

4.3 gemma-3-12b-it:终于对上

最终匹配的版本是 gemma-3-12b-it。除了分片权重外,还必须补齐:

  • tokenizer
  • processor
  • config
  • preprocessor_config.json(关键)

到这一步,依赖链才算完整。


5. 环境与依赖:不是“装不装得上”,而是“能不能稳定复现”

我这次遇到的环境问题并不花哨,但非常常见:

5.1 Conda strict priority 导致依赖不可解

典型报错:

LibMambaUnsatisfiableError

如果你用了国内镜像(例如开启 strict priority),很容易把解空间卡死。处理方式也很工程化:

  • 切回默认源,或
  • 调整 channel priority 策略

5.2 uv / pip / .venv 混用导致“看起来装了但其实没装”

我这里踩到的是:项目自带 .venv 与我的 conda 环境产生混乱。一个简单但重要的结论是:

  • 项目自带 .venv 不等于必须使用
  • 你完全可以用 conda + pip 管理,只要保证解释器和 site-packages 指向一致

6. 第一次真正跑起来前:Gemma 先 OOM

当依赖补齐之后,我第一次遇到的硬性问题是:Gemma(12B)加载/初始化阶段直接 OOM。

报错类似:

CUDA out of memory(发生在 PromptEncoder)

直觉上也合理:

  • Gemma 12B 本身就接近 20GB+ 的显存消耗
  • 3090 标称 24GB,但可用显存会被 buffer、碎片和 runtime 开销进一步挤压

6.1 解决:手动做“分卡”而不是幻想多卡自动分摊

我采取的策略:

  • GPU1:Gemma / PromptEncoder
  • GPU0:LTX diffusion 主模型

我在 DistilledPipeline.__init__ 里增加了类似 text_device 的参数,把 prompt encoder 显式放到 cuda:1,而 diffusion 放到 cuda:0

这类改动的意义在于:多卡不是自动解决显存问题的。你必须明确:每个大组件在哪张卡上。


7. 代码层的“工程坑”(不难但很耗时间)

在继续推进时,我遇到了一组很典型的“不是算法问题,但会让你卡很久”的坑:

  • SyntaxError:复制/粘贴残留(例如多余的引号、括号)
  • TabError:tabs vs spaces(Python 最经典的坑)
    • 我用 sed -i 's/\\t/ /g' 统一掉缩进
  • __init__:后定义覆盖前定义,导致你以为参数传进去了但实际没生效
  • CUDA device ordinal:你以为有 cuda:1,但其实进程只看见一张卡
    • 典型原因是设置了 CUDA_VISIBLE_DEVICES=0
    • 解决:unset CUDA_VISIBLE_DEVICES

这些问题都不“高级”,但它们会把你从“调模型”拖进“调工程”泥潭。


8. 第二次 OOM:主模型推理阶段依然爆

当 Gemma 分卡后,我以为最难的部分过去了。但真正决定“能不能跑”的,是 diffusion 主模型推理阶段的显存峰值。

即使我做了:

  • 降分辨率
  • 减少帧数
  • 尝试进一步拆分

依然出现 OOM,且位置更接近主生成阶段。

这里的核心结论是:

LTX-2.3 22B 的权重(≈46GB)只是显存需求的一部分。

推理时还会叠加:

  • 激活(diffusion 的迭代过程会放大峰值)
  • 各类中间 buffer
  • 可能的 KV cache / attention 临时张量
  • 后处理/增强组件(如果启用)

最终,你会发现 24GB 这条线对它来说太窄了。


9. 最终结论:这是一次“边界验证”

我最终得到的最重要结论是:

  • 在 4×3090(24GB)上,按当前实现与默认推理方式,LTX-2.3 22B 很难稳定跑通
  • 这不是“参数没调好”,而是资源约束与实现方式共同决定的不可行

这类项目最怕的是:你投入很多时间,最后只留下一个模糊的“没跑通”。我希望这篇复盘留下的是一个可复用的方法论:

  1. 先把系统拆成 pipeline(谁在吃资源、谁是硬依赖)
  2. 对每一段做“可测量的资源预算”(显存、CPU、磁盘、带宽)
  3. 多卡要显式规划(组件级 device placement),不要期待自动分摊
  4. 当 OOM 多次落在主模型推理峰值时,要学会及时判断“物理不可行”,避免无效优化

10. 后续可行路线(现实版)

如果你也在类似硬件上想“出结果”,大致只有三条路:

  1. CPU/NVMe offload:能跑,但速度会非常慢
  2. 真正的模型并行:需要系统性改造(不是简单把 .to(cuda:1)
  3. 换模型/换规模:选择更适合 24GB 单卡推理的版本(或更激进的蒸馏/量化方案)

结语

这次复盘对我最有价值的点,不是“搞定了一个部署”,而是把一条大模型 pipeline 的依赖链、资源峰值、以及多卡拆分的工程边界走了一遍。

一句话总结:

从“我能不能跑这个模型”
到“这个模型在这套硬件上按当前实现物理不可行”

Read more

Mac 上 Skill CLI 无法执行的坑:最后其实一条命令就够了

我在做 Amazon skills 的过程中,逐步把本地 CLI 从 Python 脚本切到 Go 二进制。这样做的好处很明显:用户不用装 Python、不用配依赖,解压 skill 后直接运行。但在 macOS 上,我们反复遇到一个看起来很玄的问题:同一个二进制,在 Linux/Windows 上正常,在 Mac 上就是执行不了。 当时遇到的现象 常见报错大概有几类: * 双击或 agent 调用 CLI 时,系统提示文件来自未知开发者,无法打开。 * 终端里执行时提示 Permission denied。 * 已经 chmod +x 了,仍然被 macOS 拦截。 * Apple

By ladydd

当我把全世界人群的基因 PCA 跑出来后,看见了一个倒 L 型

最近我把之前学的一些分子人类学知识,终于真正落地了。 不是停留在看论文、看别人画图、看别人解释“人群结构”这些概念,而是自己把数据处理完,自己跑 PCA,自己把全世界不同人群放到一张图上。 然后那一刻,我真的被击中了。 图上出现了一个非常漂亮的倒 L 型。 一端是非洲,另一端逐渐拉向东亚,中间有中东、欧洲、南亚、欧亚大陆上的各种过渡人群。它不是那种随机散点图,而是有方向、有骨架、有历史感的结构。 我第一眼看到的时候,脑子里直接冒出一句话: 这不像是一张普通统计图,这像是人类迁徙史在二维空间里留下的影子。 当然,后来我也提醒自己,PCA 不能被过度浪漫化。它不是地图,也不是时间轴,更不是“谁从哪里走到哪里”的直接证据。PCA 本质上是把高维基因差异压缩到几个主成分上,用最大方差方向把样本摊开。它可以帮助我们观察人群结构、相似性、分化和混合,但不能单独承担全部历史解释。PCA 在群体遗传学里常用于观察 population structure

By ladydd

吞吐与延迟:一个厨房比喻讲透性能压测

写于 2026-06-26。背景: MCP 服务 跑在 3 台 ClickHouse(每台 16 核 / 64G,1 分片 3 副本)上。 我们花了一整轮做公网压测,把这套系统的极限、天花板和杠杆全摸清了。这篇把"吞吐 / 延迟 / 排队"这三个最容易混的概念讲透,配我们自己的真实实测数据。 一句话结论 我们这套系统的吞吐天花板 ≈ 76 req/s。 往里塞再多并发(100、200、300、500),每秒"做完"的还是大约 76 个,多出来的全在排队。系统不会崩,只会让每个人等得更久。 天花板能不能抬?

By ladydd

四卡 3090 本地模型部署复盘:Ollama 跑通 35B,以及 GPU0 掉卡问题

这次做的是一轮真实的本地模型部署摸底。 目标不是搭一个临时 Demo,而是把一台四卡 3090 GPU 机器接进自己的日常 AI 使用环境:本机跑 Open WebUI,负责账号、会话和前端配置;GPU 机器只负责模型推理。这样以后换模型、换推理框架、重启服务,都尽量不影响本机的使用入口。 最后结论比较清楚:qwen3.5:35b 的 GGUF Q4_K_M 量化版已经通过 Ollama 跑通,本机 Open WebUI 可以接入,热加载后的聊天速度也能用;但 GPU0 存在明显稳定性问题,重启后能短暂恢复,跑过负载后又会掉到 NVML 异常状态。 状态快照 当前能用的部分: * 本机 Open WebUI 已部署,

By ladydd
陕公网安备61011302002223号 | 陕ICP备2025083092号