深度学习显存不够怎么办?

24G显存的RTX 4090D,跑LLM推理和AI绘画视频,资源怎么分配?本文从硬件配置到代码实现,手把手教你搞定。写在前面:一个很实际的问题
事情是这样的。
最近有人问我:"本地部署AI平台,到底需要什么样的硬件配置?"
说实话,这个问题问到了要害。因为现在本地AI创作已经不是什么"能跑就行"的阶段了——你要跑LLM做智能对话,还要跑ComfyUI画图生成视频,甚至还要做agentic创作闭环。这些全是GPU显存大户,一张显卡怎么分配资源,成了最关键的问题。
我的配置:

组件配置
显卡RTX 4090D,24G显存
内存32G
硬盘NVMe 2.0固态硬盘
CPU/主板一般就行,不关键

先说结论:24G显存,跑量化模型刚刚好,跑完整版模型——没戏。
一、硬件配置:显卡是王道,其他都是配角
1.1 显卡:唯一重要的硬件
这是我最有发言权的部分。

显卡显存体验
RTX 20708G图片生成勉强可以,8B量化LLM也能跑,但没法做agentic创作闭环
RTX 4090D24G量化模型推理+图像视频生成,刚刚好够用

关键经验:8G显存是"能玩"和"不能用"的分水岭。你确实能生成图片,也能跑小模型,但一旦涉及到多步骤的agentic工作流(LLM推理→画图→再推理→再画图),8G显存根本扛不住。
24G显存是什么概念?

  • 加载一个7B量化LLM模型:约4-8G显存
  • 加载一个14B量化LLM模型:约8-16G显存
  • 加载一个27B量化LLM模型:约19-22G显存
  • ComfyUI跑Zimage QwenImage量化版图像生成:约16-22G显存
  • ComfyUI跑Ltxv2.3量化版视频生成:约18-22G显存

所以24G显存的瓶颈在于:这些应用不能同时满载运行,必须做资源切换。
1.2 内存:32G够用,64G更从容
内存的作用主要是:

  • 操作系统+日常软件占用:约8-12G
  • llama.cpp模型加载时,部分层会fallback到CPU内存
  • ComfyUI的预处理和后处理也需要内存

32G是够用线,64G可以完全不用担心。
1.3 硬盘:别忽视的隐形瓶颈
这一点很多人会忽略,但在显存切换的场景下,硬盘速度直接影响切换体验
我的配置是NVMe 2.0固态硬盘。为什么说硬盘重要?

  • 模型加载依赖磁盘I/O:llama.cpp每次从显存卸载模型后,重新加载时都需要从磁盘读取模型文件。一个7B量化模型约4G,14B约8G,27B约16G+。这些数据的读取速度直接决定了"画图→对话"切换时的等待时间。
  • NVMe 2.0的性能:读取速度通常在2000-3500 MB/s左右,加载一个4G的7B量化模型大约需要1-2秒(纯I/O时间)。如果是SATA SSD(500 MB/s),同样操作需要5-8秒。如果是机械硬盘……那切换体验就别想了。
  • ComfyUI的模型加载同理:ComfyUI的checkpoint、VAE、ControlNet等模型文件也很大,硬盘速度直接影响工作流的启动速度。

关键经验:如果你经常需要在llama.cpp和ComfyUI之间切换,NVMe SSD是刚需。更好——切换等待时间可以缩短。
1.4 CPU和主板:一般不重要,但有一个例外
常规情况:AI推理和图像生成的核心计算都在GPU上,CPU只是辅助。所以CPU和主板一般就行
例外——纯CPU模式:如果你的CPU非常非常强劲(比如Threadripper、EPYC这种多核怪兽),你其实可以不依赖GPU,直接用CPU模式运行llama.cpp和ComfyUI。不过要做好比较慢的心理准备。
两种工具对CPU模式的支持程度不同:

  • llama.cpp:对CPU推理做了深度优化,支持AVX/AVX2/AVX-512等指令集加速,内存管理也很高效。用多核CPU跑7B量化模型,虽然速度远不如GPU,但完全可用,对话延迟在可接受范围内。
  • ComfyUI:支持CPU运行,但属于兼容层面的支持,并没有针对CPU做专门优化。能用,但生成一张图的时间可能是GPU的几十倍甚至上百倍。

结论:纯CPU模式适合"有顶级CPU但没有好显卡"的场景。llama.cpp的CPU体验尚可,ComfyUI的CPU体验就比较痛苦了。如果你像我一样只有一张4090D,还是把CPU当辅助、GPU当主力,这才是合理的方案。
二、核心问题:24G显存怎么分配?
2.1 一张图看懂资源竞争
┌──────────────────────────────────────────────────────┐
│ RTX 4090D — 24G 显存 │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ llama.cpp (LLM 推理) │ │
│ │ 7B 量化模型: ~4-8G 显存 │ │
│ │ 14B 量化模型: ~8-16G 显存 │ │
│ │ 27B 量化模型: ~16-22G 显存 │ │
│ │ ⚠️ 加载后常驻显存,不主动释放 │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ ComfyUI (图像/视频生成) │ │
│ │ ZImage 量化版图像生成: ~12-18G 显存 │ │
│ │ 视频生成: ~18-22G 显存 │ │
│ │ ⚠️ 推理完不主动释放显存 │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ ❌ 两个应用不能同时满载运行 │
│ ✅ 必须做显存切换调度 │
└──────────────────────────────────────────────────────┘
2.2 两种使用模式
这里涉及到一个很实际的选择:
模式一:这台机器就是模型服务器
把这台机器当成专用的AI服务器,所有资源都留给模型推理和图像生成。用其他电脑通过局域网访问。
优点:

  • 资源利用率最大化,不需要给桌面应用留资源
  • 可以后台长时间运行,不受日常使用影响
  • 适合重度AI创作用户

缺点:

  • 这台机器不能同时做其他事情
  • 需要额外的电脑来访问

模式二:日常使用+AI创作共用
这台机器既是日常办公电脑,又是AI创作平台。
优点:

  • 一台机器搞定所有事
  • 不需要额外设备

缺点:

  • 运行AI任务时,日常应用会受到资源限制
  • 需要更精细的资源管理

我的选择:模式二。这台机器就是日常办公电脑,又是AI创作平台,内存大,cpu能力用于日常办公,ai创作用显卡能力。
2.3 运行AI任务时,还剩多少资源给其他程序?
这是很多人关心的问题。实测数据:

场景显存占用剩余显存内存占用剩余内存
空闲~1G (桌面)~23G~8G~58G
仅跑7B量化LLM~8G~16G~16G~50G
仅跑ComfyUI画图~20G~4G~28G~36G
LLM+日常应用~20G~4G~28G~36G
ComfyUI+日常应用~20G~4G~28G~36G
LLM+ComfyUI切换峰值~20G~4G~28G~36G
LLM+ComfyUI同时峰值~40G不够~48G~16G

结论:

  • 如果只做单一任务(只跑LLM或只跑ComfyUI),剩余资源足够日常使用
  • 如果两个任务切换运行,切换瞬间资源紧张,但切换完成后会释放
  • 如果两个任务同时运行,系统显存不够。
  • 不建议在AI任务运行时同时运行其它大型软件

三、解决方案:显存自动切换调度
既然24G显存不能同时满载运行两个AI服务模型服务,comfyui的模型+llama.cpp模型,那就让它们轮流使用显存——用谁的时候,把另一个的显存释放掉。
3.1 核心思路:一张办公桌,两个项目
想象你只有一张办公桌(GPU显存),桌上只能放一个项目:

场景比喻实际操作
你要写文档(用llama.cpp)桌上摊开一本书(加载模型)loadLlamaModel()
你要画图(用ComfyUI)先把书放回书架,再铺开画布unloadLlamaModels() → 运行ComfyUI
画完图又要写文档把画布收起来,再去拿书cleanComfyUIVram() → loadLlamaModel()
你老婆问"画布收好了吗"你心里记着"是的"markComfyuiUsed() 标记状态

一句话总结:
"用画图前把书放好,用完画图记下来,下次写文档前先把画收起来。"
3.2 架构设计
┌─────────────────────────────────────────────────────┐
│ VRAM Manager │
│ (vram-manager.ts) │
│ │
│ 状态标记: ComfyUI 是否在用? │
│ ┌──────────────────────────────────────┐ │
│ │ _needsComfyuiCleanup: boolean │ │
│ │ _comfyuiUrlForCleanup: string │ │
│ │ _cleanPromptCache: object │ │
│ └──────────────────────────────────────┘ │
│ │
│ 核心函数: │
│ ├── unloadLlamaModels() ─── HTTP 卸载 llama │
│ ├── cleanComfyUIVram() ─── 向 ComfyUI 发清理工作流 │
│ ├── loadLlamaModel() ─── HTTP 加载 llama 模型 │
│ ├── markComfyuiUsed() ─── 标记"ComfyUI 刚用完" │
│ ├── ensureLlamaVram() ─── 需要时清理 ComfyUI │
│ └── hasEnoughVram() ─── 检查是否有足够的显存 │
└─────────────────────────────────────────────────────┘
▲ ▲
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ llama.cpp │ │ ComfyUI │
│ (localhost:8080)│ │ (localhost:8188)│
│ │ │ │
│ /models/load │ │ /prompt │
│ /models/unload │ │ /history │
│ /v1/models │ │ /upload/image │
│ /v1/chat/complet.│ │ /view │
└─────────────────┘ └─────────────────┘
3.3 核心代码实现
第一步:状态标记
// ===== 模块级全局变量(单例状态)=====

let _needsComfyuiCleanup = false
// 标记: ComfyUI 的模型是否还占着显存
// true → 下次调用 llama.cpp 前必须清理 ComfyUI 的显存
// false → 不需要额外清理

let _comfyuiUrlForCleanup = ''
// 记录: 之前使用的 ComfyUI 服务地址是哪个

let _cleanPromptCache: Record<string, any> | null = null
// 缓存: 清理 VRAM 的 ComfyUI 工作流 JSON
每次ComfyUI用完,调用这个函数立个flag:
export function markComfyuiUsed(
comfyuiUrl: string,
cleanPrompt?: Record<string, any>
): void {
_needsComfyuiCleanup = true // 立 flag
_comfyuiUrlForCleanup = comfyuiUrl // 记住它用的哪个 URL
_cleanPromptCache = cleanPrompt || null
}
第二步:llama.cpp模型的加载与卸载
加载模型(就像点外卖:先下单,然后轮询等待):
export async function loadLlamaModel(
llamaApiUrl: string,
modelName: string
): Promise<boolean> {
if (!modelName) return false

const baseUrl = normalizeBaseUrl(llamaApiUrl)

// 第一步: 发送加载请求
await fetch(`${baseUrl}/models/load`, {
method: 'POST',
body: JSON.stringify({ model: modelName }),
}).catch(() => {})

// 第二步: 轮询等待模型就绪(最多 120 秒)
const pollStart = Date.now()
while (Date.now() - pollStart < 120000) {
const res = await fetch(`${baseUrl}/v1/models`)
if (res.ok) {
const data = await res.json()
if (data.data.some((m: any) => m.id === modelName)) return true
}
await new Promise(r => setTimeout(r, 2000)) // 每 2 秒轮询一次
}
return false // 超时
}
卸载模型(把冰箱里的菜都扔出去):
export async function unloadLlamaModels(llamaApiUrl: string): Promise<boolean> {
const baseUrl = normalizeBaseUrl(llamaApiUrl)

// 查询当前加载了哪些模型
const res = await fetch(`${baseUrl}/v1/models`)
const data = await res.json()
const loadedModels = data.data.filter(m => m.status?.value === 'loaded')

if (loadedModels.length === 0) return true

// 逐个卸载
for (const model of loadedModels) {
await fetch(`${baseUrl}/models/unload`, {
method: 'POST',
body: JSON.stringify({ model: model.id }),
})
}
return true
}
第三步:ComfyUI显存清理
ComfyUI跑完任务后不会主动释放显存,需要手动触发清理。我们用一个特殊的ComfyUI工作流来实现:
{
"1": {
"class_type": "easy cleanGpuUsed",
"inputs": { "anything": ["11", 0] }
},
"11": {
"class_type": "EmptyLatentImage",
"inputs": { "width": 16, "height": 16, "batch_size": 1 }
}
}
easy cleanGpuUsed 是ComfyUI-Easy-Use插件提供的节点,它的作用是遍历GPU上的所有模型和缓存,调用torch.cuda.empty_cache()释放显存。
发送清理请求的代码:
export async function cleanComfyUIVram(
comfyuiUrl: string,
workflow: any
): Promise<boolean> {
const response = await fetch(`${comfyuiUrl}/prompt`, {
method: 'POST',
body: JSON.stringify({ prompt: workflow }),
})
const data = await response.json()
return !!data.prompt_id
}
第四步:完整的调度流程
在智能聊天服务中,每次调用LLM之前自动检查并清理:
async function callLLMStream(config, ...) {
const isLocalModel = config.apiBase.includes('127.0.0.1')

// ===== 第一步: 确保显存干净 =====
if (isLocalModel) {
const cleanPrompt = loadTemplate('clean_vram_used_api.json')
await ensureLlamaVram('127.0.0.1:8188', cleanPrompt)
}

// ===== 第二步: 确保模型已加载 =====
if (isLocalModel) {
const modelIds = (await healthData.data || []).map(m => m.id)
if (!modelIds.includes(modelToUse)) {
await loadLlamaModel(baseUrl, modelToUse)
}
}

// ===== 第三步: 开始推理 =====
const res = await fetch(llamaApiUrl, {
method: 'POST',
body: JSON.stringify({ model: 'local', messages: [...], stream: true })
})
}
ComfyUI绘图工具函数中,先释放llama.cpp的显存:
async function handleComfyUIDraw(args, sessionId) {
const settings = loadSettings()

// ===== 1. 先释放 llama.cpp 的显存占用 =====
await unloadLlamaModels(settings.llamaApiUrl)

// ===== 2. 运行 ComfyUI 工作流 =====
const result = await runComfyUIWorkflow(templateName, overrides)

// ===== 3. 标记"ComfyUI 刚用完" =====
markComfyuiUsed(settings.comfyuiUrl, cleanPrompt)

return { output: result.images }
}
四、四种典型场景的切换流程
场景一:连续对话(llama.cpp → llama.cpp)
对话1 ──→ loadModel ──→ 推理 ──→ 对话2 ──→ 推理 ...

不需要做任何清理
(模型已经在显存中)
体验:秒回,无需等待。
场景二:对话 → 画图(llama.cpp → ComfyUI)
对话 ──→ [unloadLlamaModels] ──→ 画图
│ ↑
│ 释放 llama 模型的 ~6GB VRAM
│ 给 ComfyUI 腾出空间
└───→ markComfyuiUsed()
体验:切换时有1-2秒延迟(卸载模型),画图正常进行。
场景三:画图 → 对话(ComfyUI → llama.cpp)
画图 ──→ [cleanComfyUIVram] ──→ [loadLlamaModel] ──→ 对话
↑ ↑
向 ComfyUI 发送清理指令 重新加载 llama 模型
释放 ~8GB VRAM 等待 5-15 秒
体验:切换时有5-15秒延迟(清理+加载模型),取决于模型大小。
场景四:画图 → 画图(ComfyUI → ComfyUI)
画图1 ──→ markComfyuiUsed → 画图2 ──→ 直接运行
体验:无缝切换,ComfyUI复用显存中的模型。
场景五:高频交替切换(llama.cpp ↔ ComfyUI ↔ llama.cpp ...)
这是agentic创作闭环中最常见的场景:
对话 → [卸载LLM] → 画图 → [清理ComfyUI] → [加载LLM] → 对话 → [卸载LLM] → 画图 → ...
这里有一个需要正视的问题:
唯一的缺点是,如果频繁切换llama.cpp和ComfyUI的资源,而每次任务耗时又很小,切换代价会很大。
具体来说:

切换操作耗时说明
卸载llama.cpp模型1-2秒HTTP请求+模型从显存移除
清理ComfyUI显存2-4秒发送清理工作流+等待执行完成
重新加载llama.cpp模型5-15秒模型从磁盘加载到显存,取决于模型大小和硬盘速度
单次完整切换循环8-21秒卸载→清理→重新加载

:以上耗时基于我的NVMe 2.0固态硬盘。如果你的硬盘速度不同,"重新加载模型"这一步的耗时会有明显差异:

硬盘类型读取速度7B模型加载14B模型加载27B模型加载
NVMe 4.0~7000 MB/s~1秒~2秒~4秒
NVMe 2.0(我的配置)~2500 MB/s~2秒~4秒~7秒
SATA SSD~550 MB/s~4秒~8秒~15秒
机械硬盘~150 MB/s~12秒~25秒~50秒

如果你的agentic工作流是"对话10秒→画图30秒→对话10秒→画图30秒",那每次切换浪费的时间占比可以忽略不计。
但如果是"对话2秒→画图5秒→对话2秒→画图5秒"这种高频小任务模式,切换时间甚至超过了任务本身的时间,效率会大打折扣。
但是——
Agentic完整无人监管完成这些步骤,也能值回票价。
为什么这么说?因为agentic的核心价值不在于"单次任务快多少",而在于:

  1. 无人值守:你不需要坐在电脑前手动切换应用、手动清理显存、手动加载模型。整个流程从对话到画图再到分析结果,全自动完成。
  2. 创作闭环:LLM分析需求→生成提示词→ComfyUI画图→LLM评估结果→不满意就调整提示词重新画→直到满意为止。这个闭环里可能包含5-10次切换,但每一步都是自动的。
  3. 时间成本转移:你把"等待切换"的时间成本,转移成了"不需要人工干预"的时间收益。你可以去喝杯咖啡、处理别的事情,等回来时整个创作流程已经跑完了。

一句话总结:切换有代价,但agentic的自动化价值远大于切换成本。
五、未来改进方向:让切换更聪明
既然切换代价是客观存在的,那有没有办法优化?以下是几个值得探索的方向:
5.1 预测性预加载(Speculative Preloading)
问题:每次用llama.cpp前都要等5-15秒加载模型。
思路:如果agentic工作流的模式是固定的(比如"画图→分析→画图→分析"),那系统可以预测下一步需要什么模型,提前在后台加载
// 伪代码:画图完成后,预测下一步需要LLM分析
async function afterComfyUIComplete(result) {
// 清理ComfyUI显存
await cleanComfyUIVram(comfyuiUrl, cleanPrompt)

// 预测下一步:agentic流程中画图后通常是LLM分析
// 提前开始加载LLM模型(异步,不阻塞当前流程)
predictNextStep('llm_analysis').then(modelName => {
preloadLlamaModel(llamaApiUrl, modelName)
})
}
预期效果:将"画图→对话"的切换延迟从5-15秒降低到1-3秒。
5.2 模型热驻留(Model Hot-Keep)
问题:每次切换都要卸载再加载,磁盘I/O是瓶颈。
思路:对于小模型(如7B量化版,约4-5G显存),如果剩余显存足够,可以不卸载,让模型常驻显存。只有当显存不够时才卸载。
async function ensureLlamaVram(comfyuiUrl, cleanPrompt, requiredMB = 4096) {
const freeVram = getFreeVramMB()

// 如果显存足够同时容纳LLM和ComfyUI,就不切换
if (freeVram >= requiredMB + comfyuiEstimatedUsage) {
return // 跳过切换,直接运行
}

// 显存不够,执行正常切换流程
await cleanComfyUIVram(comfyuiUrl, cleanPrompt)
}
适用场景:7B小模型+SDXL图像生成(总显存需求约12-16G,24G显存可以容纳)。
5.3 任务批处理(Task Batching)
问题:高频小任务切换,每次切换代价占比过高。
思路:将同类任务批量处理,减少切换次数。
❌ 低效模式:对话 → 画图 → 对话 → 画图 → 对话 → 画图(3次切换)
✅ 高效模式:对话×3 → 画图×3 → 对话×1(1次切换)
在agentic系统中,可以设计一个任务队列,将连续的小任务合并成批次执行:
class AgenticTaskQueue {
private llmTasks: LlmTask[] = []
private comfyuiTasks: ComfyUITask[] = []

async executeBatch() {
// 第一批:集中处理所有LLM任务
for (const task of this.llmTasks) {
await this.runLlm(task)
}

// 切换一次:卸载LLM → 加载ComfyUI
await this.switchToComfyUI()

// 第二批:集中处理所有ComfyUI任务
for (const task of this.comfyuiTasks) {
await this.runComfyUI(task)
}

// 切换一次:清理ComfyUI → 加载LLM
await this.switchToLlama()

// 第三批:LLM汇总分析结果
await this.runSummary()
}
}
预期效果:对于6个交替任务,切换次数从5次降低到2次,节省约30-60秒。
5.4 双实例并行(Dual Instance)
问题:单实例串行切换,无法并行。
思路:如果显存允许,llama.cpp和ComfyUI各跑一个轻量级实例,小任务直接并行,大任务再切换。
小任务模式(并行):
┌─────────────────────────────────────────────┐
│ 24G 显存 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ LLM 7B │ │ ComfyUI │ │ 空闲 │ │
│ │ ~5G │ │ ~8G │ │ ~11G │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────┘

大任务模式(切换):
┌─────────────────────────────────────────────┐
│ 24G 显存 │
│ ┌──────────────────────────┐ ┌──────────┐ │
│ │ ComfyUI 视频生成 │ │ 空闲 │ │
│ │ ~20G │ │ ~4G │ │
│ └──────────────────────────┘ └──────────┘ │
│ (LLM 已卸载) │
└─────────────────────────────────────────────┘
实现方式:在vram-manager中增加一个parallelMode开关,根据任务大小自动选择并行或切换模式。
5.5 模型分层缓存(Model Tiered Caching)
问题:每次加载模型都要从磁盘读,慢。
思路:借鉴CPU缓存的L1/L2/L3分层思想:

层级存储位置速度容量用途
L1GPU显存最快~24G当前正在使用的模型
L2系统内存中等~32G最近使用过的模型(llama.cpp支持mmap)
L3SSD磁盘最慢无限所有可用模型

llama.cpp本身支持mmap(内存映射),模型文件不需要完全加载到内存,而是按需从磁盘读取。结合操作系统的页面缓存,第二次加载同一个模型的速度会显著提升
优化建议

  • 确保模型文件存放在高速SSD上(NVMe最佳)。我的NVMe 2.0固态硬盘读取速度约2500 MB/s,加载7B量化模型约2秒。如果升级到NVMe 4.0(~7000 MB/s),同样操作只需约1秒——在频繁切换的场景下,这个提升是实实在在的。
  • 保持足够的系统内存(64G可以让操作系统缓存更多模型数据)
  • 对于常用的1-2个模型,可以考虑用GGUF格式并启用mlock(锁定在内存中不被交换出去)

六、辅助工具
6.1 实时显存监控
export function getFreeVramMB(): number {
const output = execSync(
'nvidia-smi --query-gpu=memory.free --format=csv,noheader,nounits'
)
return parseInt(output.trim())
}

export function hasEnoughVram(requiredMB: number = 4096): boolean {
const free = getFreeVramMB()
return free >= requiredMB
}
6.2 命令行手动卸载工具
有时候你需要手动清理llama.cpp的模型(比如调试时),可以用这个Python脚本:
class LlamaCppClient:
def __init__(self, base_url: str):
self.base_url = base_url

def unload_all_models(self) -> bool:
"""卸载全部已加载的模型"""
for model in self.get_loaded_models():
self.unload_model(model['id'])
使用方式:
python tools/llama_cpp_unload_all_models.py 127.0.0.1:8080
七、给你的建议
如果你也在考虑本地部署AI平台,我的建议是:

建议说明
显卡是核心24G显存是"能搞事情"的起步线,8G只能玩不能干正事
量化模型是刚需24G显存跑不了完整版大模型,必须用量化版(Q4_K_M、IQ4_XS等)
显存切换是必选项单卡跑多任务,必须做资源调度,否则OOM崩溃
机器定位要清晰要么当专用服务器,要么接受资源紧张——不要既要又要
内存别省32G够用,64G更从容,别为了省几百块买16G
硬盘要快模型加载依赖磁盘I/O,NVMe SSD是刚需。NVMe 2.0够用,4.0更好——切换等待时间可缩短30%-50%

八、关键文件索引

文件作用
src/shared/ai/vram-manager.ts核心调度器 - 状态追踪、加载/卸载/清理
src/main/ai_chat/comfyui-service.tsComfyUI工作流执行器
src/main/ai_chat/smart-chat-service.ts智能聊天服务 - tool handler中调度VRAM
config/comfy_templates/clean_vram_used_api.jsonVRAM清理工作流模板
tools/llama_cpp_unload_all_models.py独立卸载脚本

写在最后
这次折腾让我明白了一个道理:硬件预算有限的时候,软件调度就是生产力。
24G显存确实不够同时跑LLM和ComfyUI的满载任务,但通过合理的显存切换调度,两个应用可以轮流使用GPU,实现"一张显卡干两张显卡的活"。
另外还有一个备选思路:纯CPU模式。如果你恰好有一台CPU非常强劲的机器(Threadripper / EPYC级别),llama.cpp和ComfyUI都可以脱离GPU运行。llama.cpp对CPU做了深度优化,体验尚可;ComfyUI则是兼容支持,能用但很慢。不过对于大多数只有一张消费级显卡的用户来说,GPU为主、CPU为辅仍然是最优解。
切换确实有代价——每次8-21秒的等待,在高频小任务场景下尤其明显。但agentic系统的价值不在于"单次切换多快",而在于整个创作流程无人监管自动完成。你不需要坐在电脑前手动切换应用、手动清理显存,你可以去忙别的事情,等回来时整个创作闭环已经跑完了。
写于显存调度系统稳定运行两周之后。llama.cpp和ComfyUI在后台安静地切换着,该推理推理,该画图画图,再也没有出现过OOM。世界很安静,创作效率却翻倍了,这就是最好的结果。
参考资料

  • llama.cpp GitHub — 本地LLM推理引擎
  • ComfyUI GitHub — 节点式AI图像/视频生成
  • ComfyUI-Easy-Use — 包含cleanGpuUsed节点

本文系本地AI部署实战系列
写于2026年6月 | 关注本地AI部署与显存调度优化

编辑于 2026-07-09 · 著作权归作者所有