尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
【Bug已解决】[Bug]: GLM5.2 RuntimeError: The expanded size of the tensor (10210) must match the existing
【Bug已解决】[Bug]: GLM5.2 RuntimeError: The expanded size of the tensor (10210) must match the existing size (16384) at non-singleton dimension 1. Target sizes: [12, 10210]. Tensor sizes: [12, 16384] 解决方案一、现象长什么样在 vLLM 上跑 GLM-5.2一个超长上下文模型时推理到某个实际序列长度如 10210报错RuntimeError: The expanded size of the tensor (10210) must match the existing size (16384) at non-singleton dimension 1. Target sizes: [12, 10210]. Tensor sizes: [12, 16384]几个典型表征只在序列长度达到某个值时出现短序列正常说明问题在张量按最大长度16384预分配但运行时又被要求 expand 到实际长度10210两者冲突。报错在torch.expandexpand要求非 singleton 维度的大小必须等于原大小或 1。这里原有张量维度 1 是 16384预分配上限目标却是 10210 —— 既不等于 16384 也不等于 1于是报错。通常是 position_ids / attention mask / rotary 相关张量这些张量常按max_model_len如 16384预分配然后在运行时对实际序列做expand复用实际长度 ≠ 预分配长度时就炸。这不是模型问题而是某个按最大长度预分配、再用expand复用到的张量在运行时实际序列长度 ≠ 预分配长度时expand 的语义被误用。下面给出定位与修复。二、背景vLLM 为了效率常按max_model_len如 16384预分配位置/掩码类张量然后在每个请求上复用——常见手法是对预分配张量做tensor.expand(batch, actual_len)来避免重新分配。但expand的语义是广播它只把大小为 1 的维度展开到目标大小已经在维度上非 1 的大小必须保持原值。如果预分配张量的第 1 维已经是 16384非 1你expand(..., 10210)要求它变成 10210就违反规则 → RuntimeError。正确做法有两种预分配时用 singleton 维度如果打算expand预分配时第 1 维应为 1[12, 1]运行时expand(12, 10210)合法1→10210 广播或不用 expand用切片/索引实际序列长度确定后直接tensor[:, :actual_len]取前 actual_len 列而不是 expand 到另一个长度。GLM-5.2 这个案例预分配成了[12, 16384]非 1运行时要expand到[12, 10210]失败。根因是预分配维度与 expand 语义不匹配。修复就是要么预分配 singleton 维度 expand要么用切片代替 expand。下面用可运行代码复现并修复。三、根因拆成两条根因预分配张量第 1 维是 16384非 singleton却被 expand 到 10210expand要求非 singleton 维度大小不变。预分配[12,16384]后expand(12,10210)非法。根因是预分配维度选择错误应为 1 才能 expand。用 expand 做按实际长度截取是误用实际想要的是取前 actual_len 列该用切片[:, :actual_len]而非expand广播。根因是混淆了 expand广播与 slice截取的语义。修复方向预分配张量时若计划expand复用第 1 维设为 1singleton运行时expand到实际长度或干脆不用 expand直接切片到实际长度最稳妥无论预分配多大都能取。四、最小可运行复现下面复现expand非 singleton 维度到不同大小的错误import torch def naive_reuse(preallocated, actual_len): 现状预分配 [12,16384]运行时 expand 到 [12, actual_len]。 # preallocated.shape [12, 16384] return preallocated.expand(12, actual_len) # 非 singleton 维 16384 → 10210 非法 pre torch.zeros(12, 16384) try: naive_reuse(pre, 10210) except RuntimeError as e: print(复现:, e) # expanded size 10210 must match 16384复现: ...must match 16384即复现了 GLM-5.2 的报错维度/数字不同但本质一致。下面用切片修复。五、解决方案第一层最小直接修复最小修复不要用expand去截取不同长度直接用切片[:, :actual_len]或预分配 singleton 维度再用expand。def reuse_by_slice(preallocated, actual_len): 正确用切片取前 actual_len 列无论预分配多大都能取。 return preallocated[:, :actual_len] def reuse_by_expand(preallocated_singleton, actual_len): 正确预分配时第 1 维为 1singleton运行时 expand 合法。 # preallocated_singleton.shape [12, 1] return preallocated_singleton.expand(12, actual_len) # 1 → actual_len 广播 # 复现修复 pre torch.zeros(12, 16384) out reuse_by_slice(pre, 10210) print(切片复用形状:, tuple(out.shape)) # [12, 10210] # 若用 expand预分配必须 singleton pre_s torch.zeros(12, 1) out2 reuse_by_expand(pre_s, 10210) print(expand 复用形状:, tuple(out2.shape)) # [12, 10210]这一层改动让按实际序列长度复用预分配张量既可用切片最稳也可用正确的 singleton-expand不再触发 RuntimeError。六、解决方案第二层结构化改进把序列长度自适应张量复用做成结构化组件统一一个LengthAdaptiveTensor预分配按 max_len运行时用切片取实际长度不依赖 expand 语义最稳并支持实际长度超过预分配的告警/动态扩容。import torch from dataclasses import dataclass dataclass class SeqTensorConfig: batch: int max_len: int feat: int 1 # 如 position 的额外维 class LengthAdaptiveTensor: def __init__(self, cfg: SeqTensorConfig, init_fn): # 预分配 [batch, max_len, feat]运行时切片到实际长度 self.cfg cfg self.data init_fn((cfg.batch, cfg.max_len, cfg.feat)) def for_length(self, actual_len: int) - torch.Tensor: if actual_len self.cfg.max_len: raise ValueError( f实际长度 {actual_len} 超过预分配 max_len {self.cfg.max_len}。 f请调大 max_model_len 或启用动态扩容。) # 切片取前 actual_len不依赖 expand语义清晰且无维度冲突 return self.data[:, :actual_len, :] # 用法position_ids / mask 类张量 cfg SeqTensorConfig(batch12, max_len16384, feat1) lat LengthAdaptiveTensor(cfg, lambda s: torch.arange(s[1]).unsqueeze(0) .unsqueeze(-1).expand(s[0], s[1], s[2]).clone()) seg lat.for_length(10210) print(实际序列张量形状:, tuple(seg.shape)) # [12, 10210, 1]LengthAdaptiveTensor把预分配 按实际长度切片集中运行时永远用[:, :actual_len]而非expand到不同长度彻底规避维度冲突。七、解决方案第三层断言 / CI 守护张量 expand 错误最怕线上长序列才崩。用断言守两条不变量def check_seq_tensor_invariants(cfg: SeqTensorConfig, actual_len: int): lat LengthAdaptiveTensor(cfg, lambda s: torch.zeros(s)) seg lat.for_length(actual_len) # 不变量 1输出第 1 维必须等于实际长度不是预分配 max_len assert seg.shape[1] actual_len, f输出长度 {seg.shape[1]} ! {actual_len} # 不变量 2不得用 expand 到不同非 singleton 大小隐含用切片 # 通过输出形状正确间接保证 assert seg.shape[1] cfg.max_len return True def test_seq_tensor_reuse(): cfg SeqTensorConfig(batch12, max_len16384, feat1) check_seq_tensor_invariants(cfg, 10210) check_seq_tensor_invariants(cfg, 500) # 超 max_len 应清晰报错而非 expand 崩 try: LengthAdaptiveTensor(cfg, lambda s: torch.zeros(s)).for_length(20000) raise AssertionError(超长应被拦) except ValueError: pass print(OK: 序列长度自适应张量不变量通过) if __name__ __main__: test_seq_tensor_reuse()把test_seq_tensor_reuse接进 CI覆盖短/实际/超长三类长度锁死切片复用逻辑。八、排查清单GLM-5.2 报 expanded size ... must match ... at non-singleton dimension 1按序查先确认是expand到不同非 singleton 大小报错明确说expanded size X must match existing Y。X实际长度Y预分配长度。两者不等且都非 1 → expand 非法。找预分配张量搜torch.zeros(..., 16384)/ 按 max_model_len 分配的 position_ids / attention_mask / rotary 相关张量。别用 expand 截取用切片tensor[:, :actual_len]取前 actual_len 列无论预分配多大都合法是最稳的修复。若坚持用 expand预分配必须 singleton第 1 维设为 1[12,1]运行时expand(12, actual_len)才合法1→actual_len 广播。统一用LengthAdaptiveTensor所有按序列长度复用预分配张量的地方走同一组件避免有的用 expand、有的用切片、风格混乱踩坑。超长告警实际长度超过预分配 max_len 时清晰报错或动态扩容别让expand到更大长度再次触发。CI 接test_seq_tensor_reuse覆盖短/实际/超长三类锁死输出长度实际长度、不用非法 expand。九、小结GLM-5.2 报 expanded size (10210) must match existing size (16384) 的根因是某个按max_model_len(16384) 预分配、第 1 维非 singleton 的张量在运行时被用expand到实际长度(10210)而expand不允许非 singleton 维度变大小。三层修复第一层reuse_by_slice用[:, :actual_len]切片取实际长度最稳不依赖 expand 语义若用 expand预分配必须 singleton 维度[12,1]第二层LengthAdaptiveTensor结构化组件预分配按 max_len、运行时统一切片到实际长度、超长清晰报错第三层CI 断言守住输出第 1 维实际长度 / 超长被拦任何非法 expand 立即红。落实后GLM-5.2 在任意实际序列长度下位置/掩码类张量都用切片复用预分配缓冲不再因expand非 singleton 维度冲突而崩溃。
RELATED

相关推荐

从 0 到 1 构建 AI 需求分析引擎:Skills 技术架构与落地全复盘

从 0 到 1 构建 AI 需求分析引擎:Skills 技术架构与落地全复盘

从 0 到 1 构建 AI 需求分析引擎:Skills 技术架构与落地全复盘 需求分析不是把一段自然语言丢给大模型,然后等待一份“看起来像 PRD”的回答。 真正可落地的方案,必须把需求理解、知识约束、结构化编译、冲突校验、接口推导和工程治理串成一条可验证的生产链路。 很多团队做…

📅 2026/9/12 2:01:56
GBase 8s SSC共享存储集群四大核心能力介绍

GBase 8s SSC共享存储集群四大核心能力介绍

从技术层面的四大核心突破,到金融、民政等关键领域的长期实战沉淀,南大通用GBase 8s SSC共享存储集群(gbase database)用真实落地成果,印证了国产共享存储数据库的硬核实力,打破了核心领域对海外数据库的依…

📅 2026/9/12 6:46:21
GBase 8s SSC共享存储集群以硬核实力入选2026产业图谱

GBase 8s SSC共享存储集群以硬核实力入选2026产业图谱

2026可信数据库大会重磅发布新版中国数据库产业图谱,首次新增共享存储架构数据库独立赛道,南大通用GBase 8s SSC共享存储集群(gbase database)成功入选,获得行业权威背书。作为适配政企核心业务的国产数据库架构方案&a…

📅 2026/9/12 2:27:12
MORE NEWS

更多资讯

📰

基于Java的视频会议系统:WebRTC信令与Spring Boot实战

简介:基于Java的视频会议系统是一份面向Java学习者和毕业设计人群的完整项目资料,包含可运行的软件程序与配套WORD论文文档。项目以JMF多媒体框架处理音视频,基于RTP协议进行实时传输,并综合运用Socket网络编程与多播技术&#xf…

📰

哲学僵尸与AI意识:超越图灵测试的智能评估

1. 哲学僵尸测试:当图灵测验遇上意识难题第一次听说"哲学僵尸"这个概念是在研究生时期的认知科学课上。教授用粉笔在黑板上画了个歪歪扭扭的人形,然后突然转身问我们:"如果这个生物能完美模仿人类行为,但它内部其实…

📰

Hindsight Go Client 完整指南:用 Go 接入 Agent 记忆 API(Retain / Recall / Reflect)

Hindsight Go Client 完整指南:用 Go 接入 Agent 记忆 API(Retain / Recall / Reflect) 【免费下载链接】hindsight Hindsight: Agent Memory That Learns 项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight 本篇技…

📰

病例资料对不上报告规范?医学论文里,多半是两套叫法没接上

医学论文里病例资料整理不规范,卡点常常不在先看哪份、后看哪份,而在报告规范列出的条目,跟你手上记录用的叫法不是一套词。先把这层对应接上再动手抽数据,返工能少掉一大半。骨架可以先借免费智能大纲生成立起来,再按…

📰

Raspberry Pi Pico硬件开发入门:MicroPython固件烧录与REPL实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

SkillPort企业学习平台:功能解析与实施指南

1. SkillPort平台概述SkillPort是全球领先的企业级数字学习平台,由跨国教育科技公司SkillSoft开发运营。这个云端学习管理系统(LMS)自2003年推出以来,已经服务了包括财富500强中85%企业在内的全球客户群体。不同于普通在线教育平台,SkillPort…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬