【Bug已解决】[Bug]: Combination of sleep mode and speculative decoding cause crash (ROCm / MI250) 解决方案
【Bug已解决】[Bug] Combination of sleep mode and speculative decoding cause crash (ROCm MI250) 解决方案一、现象长什么样在 AMD MI250ROCm上同时开启sleep 模式空闲时释放显存和speculative decoding投机解码 / MTP 多 token 预测后一旦经历「sleep → wake_up → 第一次带投机解码的推理」进程崩溃。栈通常指向投机解码层RuntimeError: draft model KV cache is None after wake_up; cannot run speculative step或者更靠内核层ROCm Habana/CK error: hipMalloc returned nullptr for draft_workspace (size...)几个特征单独开 sleep 模式不开 spec decode一切正常单独开 spec decode不 sleep也正常。两者叠加才炸。只在「唤醒后第一次」投机解码推理时炸唤醒后如果先跑几次普通推理再跑投机解码有时能过——因为普通推理顺手把某些 buffer 重建了。在 MI250 这类 ROCm 卡上必现NVIDIA 卡上不一定ROCm 的显存分配失败返回 nullptr 而非抛异常更隐蔽。本质sleep 把投机解码相关的显存draft 模型、draft workspace、bonus token 缓冲一起释放了但 wake_up 只重建了主模型没重建 spec decode 那一摊第一次投机前向访问到 None/未分配的 buffer 就崩。二、背景先理清两个机制各自干什么以及它们叠加时的隐患。speculative decoding以 MTP 为例需要比普通解码多一套资源draft 模型或 MTP 头一个比主模型小、用来「猜」接下来几个 token 的模型常驻显存。draft workspace投机每一步临时存放候选 token、draft 概率、bonus token 的缓冲区。独立的 draft KV cachedraft 模型自己也要 KV 缓存。sleep 模式的做法是把「引擎持有的显存」整体 offload/释放。理想情况下它应该记录「我释放了哪些」wake_up 时按原样全部恢复。问题就出在「全部恢复」这件事上主模型的恢复逻辑写得很完整但 spec decode 那套资源尤其是 draft workspace 和 draft KV cache在 sleep 的「释放清单」和 wake_up 的「重建清单」里对不齐——要么释放了没登记要么登记了没重建。MI250 上因为显存分配失败是静默返回 nullptr而不是像 CUDA 那样抛cudaErrorMemoryAllocation这个不一致更难被早期发现一直藏到第一次投机前向才暴露。三、根因根因是wake_up 的「重建清单」遗漏了投机解码专属资源导致 draft 模型/draft workspace/draft KV 在唤醒后处于未初始化状态三层第一层主因spec decode 资源不在 sleep/wake 的对称清单里。sleep 时释放了 draft workspace因为它挂在引擎的某个子模块上被一并free了但 wake_up 的恢复函数只遍历了「主模型权重 主 KV cache」两个清单没遍历「spec decode 子模块」。于是 draft workspace 永久变成 None/未分配。第二层ROCm 的 nullptr 让问题延迟暴露。在 NVIDIA 上cudaMalloc失败会立刻抛异常wake_up 阶段就能被发现而 ROCm 上hipMalloc返回 nullptr代码如果没做if ptr is None检查就会带着 nullptr 继续跑直到真正往这个 buffer 写数据投机解码第一步才段错误/抛 RuntimeError。这解释了「为什么只在 MI250 上必现、且只在第一次投机前向炸」。第三层投机解码层假设 draft 资源一定就绪。spec decode 的前向代码里直接draft_kv_cache.advance()、draft_workspace.zero_()没有「若未初始化则先重建」的兜底。它假设「只要引擎 RUNNINGspec decode 资源就必然就绪」——这个假设在 sleep/wake 场景下被打破。一句话sleep 释放了 spec decode 的显存但 wake_up 没重建ROCm 的静默 nullptr 把崩溃推迟到第一次投机前向而 spec 层本身又没做就绪性兜底。四、最小可运行复现下面用纯 Python 模拟「sleep 释放了主draft 两类资源但 wake_up 只恢复了主、漏了 draft随后访问 draft 时崩溃」的控制流不需要 GPU用普通对象模拟显存句柄class Buffer: def __init__(self, name): self.name name self.ptr object() # 模拟已分配的显存句柄 def free(self): self.ptr None def ready(self): return self.ptr is not None def sleep(engine): for buf in engine.buffers.values(): buf.free() # 全部释放 engine.state SLEEPING def wake_up_buggy(engine): # 只重建主模型漏了 draft engine.buffers[main].ptr object() engine.buffers[main_kv].ptr object() # draft_workspace / draft_kv 没重建 - 仍是 None engine.state RUNNING def speculative_step(engine): # spec 层假设 draft 资源就绪 if not engine.buffers[draft_workspace].ready(): raise RuntimeError(draft workspace is None after wake_up) return speculated def main(): engine type(E, (), {})() engine.buffers { main: Buffer(main), main_kv: Buffer(main_kv), draft_workspace: Buffer(draft_workspace), draft_kv: Buffer(draft_kv), } engine.state RUNNING sleep(engine) wake_up_buggy(engine) print(main ready:, engine.buffers[main].ready()) print(draft ready:, engine.buffers[draft_workspace].ready()) try: speculative_step(engine) except RuntimeError as e: print(复现成功:, e) if __name__ __main__: main()跑出来会打印draft ready: False然后复现成功: draft workspace is None after wake_up与线上「唤醒后 draft 资源缺失」完全一致。五、解决方案第一层最小直接修复最省事的救火要么别同时开 sleep 和 spec decode要么 wake_up 后强制重建 spec decode 资源。临时做法是在 wake_up 完成后显式调一次 spec decode 的初始化def wake_up_safe(engine): # 先按原逻辑恢复主模型 restore_main_model(engine) # 关键补一步——确保 spec decode 资源也重建 if engine.spec_decode_enabled: engine.draft_model rebuild_draft_model(engine) engine.draft_workspace allocate_workspace(engine) engine.draft_kv_cache rebuild_draft_kv(engine) engine.state RUNNING如果你只是想先让服务不崩、不在乎 sleep 省的那点显存最简单是关掉 sleep 模式llm LLM( model..., speculative_config{method: mtp, ...}, # 不启用 sleep不要调用 /sleep规避叠加 )六、解决方案第二层结构性改进第一层是「补一步」第二层是「让 sleep/wake 把 spec decode 资源纳入统一的对称清单」从设计上消灭遗漏。核心把「所有需要随 sleep 释放、随 wake 重建的资源」集中注册到一个ResourceRegistrysleep 遍历释放、wake 遍历重建spec decode 子模块在初始化时主动注册自己的资源。from dataclasses import dataclass, field from typing import Dict, Callable dataclass class ManagedResource: name: str allocate: Callable[[], object] release: Callable[[object], None] handle: object None class ResourceRegistry: def __init__(self): self._res: Dict[str, ManagedResource] {} def register(self, res: ManagedResource): res.handle res.allocate() self._res[res.name] res def sleep_all(self): for res in self._res.values(): if res.handle is not None: res.release(res.handle) res.handle None def wake_all(self): for res in self._res.values(): if res.handle is None: res.handle res.allocate() # 统一重建不漏项 # spec decode 子模块在初始化时注册自己的资源 def init_spec_decode(registry: ResourceRegistry, engine): registry.register(ManagedResource( namedraft_workspace, allocatelambda: allocate_workspace(engine), releaselambda h: h.free(), )) registry.register(ManagedResource( namedraft_kv_cache, allocatelambda: rebuild_draft_kv(engine), releaselambda h: h.free(), )) registry.register(ManagedResource( namedraft_model, allocatelambda: rebuild_draft_model(engine), releaselambda h: h.unload(), ))这样无论以后加多少类资源只要「注册进 registry」sleep/wake 永远对称不会再出现「释放了没重建」。七、解决方案第三层断言 / CI 守护把「wake_up 后所有注册资源必须就绪」和「spec decode 前向前做就绪检查」固化成测试import pytest def test_sleep_wake_restores_all_registered(): reg ResourceRegistry() reg.register(ManagedResource(main, lambda: object(), lambda h: None)) reg.register(ManagedResource(draft_ws, lambda: object(), lambda h: None)) reg.sleep_all() # sleep 后都应释放 assert reg._res[main].handle is None assert reg._res[draft_ws].handle is None reg.wake_all() # wake 后都必须重建 assert reg._res[main].handle is not None assert reg._res[draft_ws].handle is not None def test_spec_decode_ready_before_forward(): engine make_engine(spec_decodeTrue) engine.sleep() engine.wake_up() # 投机前向前断言 draft 资源就绪 assert engine.draft_workspace.ready() assert engine.draft_kv_cache.ready() def test_speculative_step_raises_if_not_ready(): engine make_engine(spec_decodeTrue) engine.sleep() engine.wake_up_buggy() # 故意用漏重建的版本 with pytest.raises(RuntimeError): engine.speculative_step() def test_rocm_nullptr_detected(): # 模拟 ROCm 静默返回 nullptr必须被显式检查捕获 ptr None # hipMalloc 返回 nullptr assert ptr is None, hipMalloc 返回 nullptr 必须被检查不能带病前进再加一个端到端回归MI250 模拟下sleepwakespec decode 跑 10 轮不崩def test_sleep_wake_spec_decode_loop_stable(): engine make_engine(spec_decodeTrue, backendrocm) for _ in range(10): engine.sleep() engine.wake_up() out engine.generate(hello, use_speculativeTrue) assert out is not None八、排查清单看栈是否指向draft_*/speculative相关符号且发生在 wake_up 后的第一次推理 → 坐实本问题。单独关 spec decode 试一次单独关 sleep 试一次定位是不是「叠加」引发。ROCm 上检查是否有hipMalloc returned nullptr的日志静默失败需主动 grep。临时救火wake_up 后显式重建 draft 资源或直接不同时开 sleep 与 spec decode。长期修复把 spec decode 资源注册进统一的 ResourceRegistrysleep/wake 对称管理。投机解码前向前加「资源就绪」断言避免带 None 前进。升级 vLLM 到合了 sleepspec decode 兼容修复的版本并跑上面的 sleep/wake 循环回归。九、小结sleep spec decode 在 MI250 上崩溃不是 ROCm 硬件的锅而是sleep 释放了投机解码的显存draft 模型/workspace/KVwake_up 却只重建了主模型导致 draft 资源在唤醒后处于未初始化状态ROCm 的静默 nullptr 又把崩溃推迟到第一次投机前向才暴露。最小修复是 wake_up 后补重建 draft 资源或干脆不同时开两者结构性修复是用统一 ResourceRegistry 让 sleep/wake 对所有注册资源对称最后用 pytest 把「唤醒后资源全就绪」和「spec 前向前就绪检查」锁死。抓住「sleep/wake 必须对称覆盖每一个子系统的资源」这条叠加功能的稳定性坑都能照此化解。

相关新闻

【2026计算机毕设选题】计算机毕设全新推荐项目选题指南

【2026计算机毕设选题】计算机毕设全新推荐项目选题指南

ssm212基于ssmvue的外卖点餐系统vue ssm214高校食堂订餐系统jsp ssm216公司人力资源管理系统设计实现vue ssm217基于web技术下的汽车站车辆运管系统开发与设计vue ssm219一中体育馆管理系统的设计与实现vue ssm220传统文化网站vue ssm221新锐台球厅管理系统的设计与实现vue ssm…

2026/7/28 10:51:11 阅读更多 →
G-Helper:3步轻松掌控华硕笔记本性能,告别臃肿控制软件

G-Helper:3步轻松掌控华硕笔记本性能,告别臃肿控制软件

G-Helper:3步轻松掌控华硕笔记本性能,告别臃肿控制软件 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook,…

2026/7/28 10:51:11 阅读更多 →
Python爬虫实现网络小说热度分析与可视化

Python爬虫实现网络小说热度分析与可视化

1. 项目概述:网络小说热度分析的现实需求 网络文学市场规模近年来呈现爆发式增长,2023年行业规模已突破300亿元。在这个内容为王的时代,准确捕捉读者偏好、分析作品热度变化趋势,对于内容创作者、平台运营者和IP开发者都具有重要价…

2026/7/28 10:51:11 阅读更多 →

最新新闻

如何实现企业级Windows 11系统精简优化:Tiny11Builder深度解析与最佳实践指南

如何实现企业级Windows 11系统精简优化:Tiny11Builder深度解析与最佳实践指南

如何实现企业级Windows 11系统精简优化:Tiny11Builder深度解析与最佳实践指南 【免费下载链接】tiny11builder Scripts to build a trimmed-down Windows 11 image. 项目地址: https://gitcode.com/GitHub_Trending/ti/tiny11builder 在数字化转型加速的今天…

2026/7/28 11:07:16 阅读更多 →
TegraRcmGUI终极指南:3分钟掌握Switch破解与RCM注入工具

TegraRcmGUI终极指南:3分钟掌握Switch破解与RCM注入工具

TegraRcmGUI终极指南:3分钟掌握Switch破解与RCM注入工具 【免费下载链接】TegraRcmGUI C GUI for TegraRcmSmash (Fuse Gele exploit for Nintendo Switch) 项目地址: https://gitcode.com/gh_mirrors/te/TegraRcmGUI TegraRcmGUI是一款基于C开发的图形化注入…

2026/7/28 11:07:16 阅读更多 →
流放之路2物品过滤器终极指南:如何一键优化你的拾取体验

流放之路2物品过滤器终极指南:如何一键优化你的拾取体验

流放之路2物品过滤器终极指南:如何一键优化你的拾取体验 【免费下载链接】NeverSink-Filter-for-PoE2 This is a lootfilter for the game "Path of Exile 2". It adds colors, sounds, map icons, beams to highlight remarkable gear and inform the us…

2026/7/28 11:07:16 阅读更多 →
物联网安全升级:SE050安全元件与TM4C1294NCPDT的完美结合

物联网安全升级:SE050安全元件与TM4C1294NCPDT的完美结合

1. 物联网安全现状与SE050的定位在2023年的物联网安全态势报告中,全球每天新增的物联网设备达到惊人的150万台,但其中近70%的设备存在中高危安全漏洞。传统MCU方案(如STM32系列)虽然成本低廉,但在密钥存储、安全启动、…

2026/7/28 11:07:16 阅读更多 →
物联网设备安全芯片SE050与PIC18LF4515集成方案

物联网设备安全芯片SE050与PIC18LF4515集成方案

1. 为什么物联网设备需要专用安全芯片?在智能家居和工业物联网项目中,开发者常面临一个两难选择:使用通用MCU虽然成本低,但安全防护薄弱;采用高端安全方案又会导致BOM成本飙升。这正是SE050安全元件与PIC18LF4515组合的…

2026/7/28 11:07:16 阅读更多 →
Windows 11任务栏歌词显示终极指南:如何让歌词在任务栏上实时同步

Windows 11任务栏歌词显示终极指南:如何让歌词在任务栏上实时同步

Windows 11任务栏歌词显示终极指南:如何让歌词在任务栏上实时同步 【免费下载链接】Taskbar-Lyrics BetterNCM插件,在任务栏上嵌入歌词,目前仅建议Windows 11 项目地址: https://gitcode.com/gh_mirrors/ta/Taskbar-Lyrics 还在为听歌…

2026/7/28 11:06:16 阅读更多 →

日新闻

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:43 阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:43 阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:43 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/28 8:29:16 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻