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

一次 generate-prompts 服务连续超时事故的完整排查记录

背景 一个平时很稳定的服务,在 2026-04-02 这天突然出现“连续失败”。 最让人难受的不是失败本身,而是失败信息太少:日志里只有一串「第 1 次请求失败」,没有异常类型、没有耗时、没有栈。 这种时候人的直觉会把怀疑撒向四面八方:逻辑是不是坏了、参数是不是不对、上游是不是抽风、网络是不是波动……但没有证据,一切都只是猜。 1. 先把故障“照亮”:只补日志,不动行为 线上系统已经跑了很久,第一原则是:先让问题可见,但不要一上来就改主逻辑。 我加的日志只做两件事: * 把“这次请求到底发生了什么”讲清楚 * 保持所有行为不变(重试次数、超时、请求参数、返回解析都不动) 具体补充项包括: * 请求开始时的关键信息(目标地址、超时、参数摘要、prompt 长度) * 当前是第几次重试、总重试次数 * 每次请求耗时

By ladydd

快手 KAT-Coder-Pro V2 模型测试

市面上几乎没人聊这个模型,反倒让我很好奇,我决定全面测评使用一下 StreamLakeStreamLake溪流湖是快手toB视频云平台,提供领先的音视频AI解决方案。包含KAT-Coder智能编程助手、万擎大模型平台、视频云服务、直播云、点播云、实时音视频RTC等产品。基于前沿AI技术和音视频算法,为企业提供智能代码生成、视频处理、内容理解、智能审核等全链路服务,助力数字化转型。StreamLakeStreamLake 付完款发现上下文只有256K , 到今天来说 已经落后了 而且不支持视觉,也没有mcp接入 联网搜索之类的东西 确实是远远落后了 时隔半年再次看快手模型的官网,发现现在几乎就主打这一个模型了 coding plan用这个,然后api 调用这个是, 接入openclaw 也是这个,总之一个模型走天下,看上去太穷了,像是随时跑路的状态,但其实我很喜欢这种方式, 一个模型通杀所有场景 哈哈哈 接入 opencode 中使用 开了一个新的项目,决定保守一点,先让写文档, 之后再生成代码 下面是实际的体验 1. 不断 chat

By ladydd

在 Mac mini 上把 OpenClaw 跑起来:从证书坑到 Qwen 接入(实战记录)

这篇记录的是我在一台 Mac mini(中国大陆网络环境)上安装并跑通 OpenClaw 的全过程:从一键安装开始,接入阿里 DashScope 的 OpenAI 兼容接口(Qwen),一路踩到 Node TLS 证书链问题,最后用 nvm 彻底解决,并成功进入 openclaw tui。 背景与目标 我想在本机快速体验 OpenClaw(一个可执行工具调用的 AI Agent 框架)。目标很明确: * 在 macOS 上装起来 * 不依赖海外大模型(尽量不需要外网) * 用 Qwen(DashScope 的 OpenAI-compatible 接口)作为模型后端 * 最终能启动到交互界面(TUI) 环境 * 设备:Mac mini

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