ktransformers icon indicating copy to clipboard operation
ktransformers copied to clipboard

struct.error: unpack requires a buffer of 4 bytes when loading Qwen3Moe GGUF file with ktransformers

Open udun01 opened this issue 4 months ago • 8 comments

检查清单

  • [x] 1. 我已经搜索过相关问题,但未能获得预期的帮助
  • [x] 2. 该问题在最新版本中尚未修复
  • [x] 3. 请注意,如果您提交的BUG相关 issue 缺少对应环境信息和最小可复现示例,我们将难以复现和定位问题,降低获得反馈的可能性
  • [x] 4. 如果您提出的不是bug而是问题,请在讨论区发起讨论 https://github.com/kvcache-ai/ktransformers/discussions。否则该 issue 将被关闭
  • [x] 5. 为方便社区交流,我将使用中文/英文或附上中文/英文翻译(如使用其他语言)。未附带翻译的非中文/英语内容可能会被关闭

问题描述

在使用 ktransformers 加载 Qwen3-30B-A3B的 GGUF 量化文件时,出现 struct.error: unpack requires a buffer of 4 bytes 错误,导致模型无法加载。该 GGUF 文件已验证文件头为合法的 GGUF 格式,哈希值与网站上的文件相同,但 ktransformers 的 GGUFLoader 解析时始终失败。

复现步骤

1、使用了ModelScope内unsloth/Qwen3-30B-A3B-GGUF的两个版本(Q4_0,Q8_0) 2、命令 2-1.(base) nh@CHS:~/ktransformers$ conda activate kt-LLM 2-2.(kt-LLM) nh@CHS:~/ktransformers$ python ktransformers/server/main.py --model_path /home/nh/LLM-Model/Qwen3-30B-A3B --gguf_path /home/nh/LLM-Model/Qwen3-30B-A3B-GGUF/ --optimize_config_path ktransformers/optimize/optimize_rules/Qwen3Moe-serve.yaml

环境信息

操作系统:Ubuntu 22.04 Python 版本:3.11.5 ktransformers 版本:已经为最新 依赖库版本: torch:2.8.0+cu128 llama-cpp-python:0.1.50 flashinfer:0.2.0 GPU:NVIDIA RTX 5080 CUDA 版本:12.8

udun01 avatar Aug 22 '25 07:08 udun01

降到tag为v0.3.2重新编译试一下?

PPXGS avatar Aug 22 '25 11:08 PPXGS

短结论:这是典型的 GGUF 头部或偏移读错位。常见三类原因

  1. 文件不完整或被代理改写。分片未合并、断点续传截断、下载到 HTML 页面。
  2. GGUF 版本或格式不兼容,文件版本高于当前 ktransformers 的 GGUFLoader 支持。
  3. Qwen3-MoE 的 GGUF 需要 loader 具备 MoE 支持,旧版本解析器会在读取 header 或 tensors 索引时触发 unpack requires a buffer of 4 bytes

快速自检(5 分钟能确定原因)

  1. 验证文件本体

    • sha256sum <model.gguf> 对照发布页校验
    • wc -c <model.gguf> 看字节数是否和官方一致
    • 若是分片 *.gguf.* 记得先 cat part* > model.gguf 合并
    • 确认不是下载到重定向 HTML,file <model.gguf>head -c 8 <model.gguf> 应该出现 GGUF 魔数
  2. 用独立工具校验 GGUF

    • llama-cli --print-gguf <model.gguf> 或等价脚本
    • 能打印出 header 和 tensors 列表,说明文件本体 OK。如果这里也报错,就是文件或版本问题
  3. 对齐 loader 与 MoE 支持

    • 升到 ktransformers 最新 master 或 nightly,确保包含 GGUF 的 MoE 解析支持
    • 若最新仍失败,先用非 MoE 的 Qwen GGUF 验证一遍,排除模型侧因素
    • 作为对照,用 llama.cpp 加载同一 GGUF。如果 llama.cpp 正常而 ktransformers 失败,基本就是 GGUFLoader 兼容性

常见修复

  • 重新下载,用 aria2c -c -x16 之类并比对校验和,避免代理对 Range 响应做压缩或改写
  • 合并分片后再加载
  • 升级到包含 MoE GGUF 支持的 ktransformers 版本。无法升级时,临时改用非 MoE GGUF 或用 llama.cpp 推理做验证

如果你能贴出:sha256sumllama-cli --print-gguf 的前 30 行、以及你当前的 ktransformers 版本号,我可以帮你断点定位到底是文件问题还是 loader 兼容问题。

onestardao avatar Aug 23 '25 02:08 onestardao

降到tag为v0.3.2重新编译试一下?

使用pip show ktransformers,version为0.3.2+cu128torchavx2

udun01 avatar Aug 25 '25 01:08 udun01

看起来这不是你代码的问题,而是 GGUF 文件和 loader 版本/能力不匹配。常见排查步骤:

  1. 先校验 GGUF 文件完整性,sha256sum 对照官方值,再用 gguf 工具打印 header 和 tensors 列表,确认能正常读。
  2. 你用的是 Qwen3 MoE 变体,ktransformers 老版本对 MoE-GGUF 支持不完整,建议先试最新 nightly 版本;也可以交叉用 llama.cpp 打开同一个文件,如果能读说明就是 loader 差异。
  3. 检查 config 里的参数(n_ctx, heads 等)是否和 GGUF meta 信息一致,不一致也会触发越界报错。

如果是文件损坏,用 aria2c -x16 重新下载一遍;如果 llama.cpp 正常、ktransformers 报错,那就是 MoE 支持还没完全补上。

这种情况在我们的 ProblemMap 里对应 No.14(Bootstrap Ordering / 加载顺序问题),有完整 checklist 可以参考:
https://github.com/onestardao/WFGY/blob/main/ProblemMap/README.md

onestardao avatar Aug 25 '25 01:08 onestardao

看起来这不是你代码的问题,而是 GGUF 文件和 loader 版本/能力不匹配。常见排查步骤:

  1. 先校验 GGUF 文件完整性,sha256sum 对照官方值,再用 gguf 工具打印 header 和 tensors 列表,确认能正常读。
  2. 你用的是 Qwen3 MoE 变体,ktransformers 老版本对 MoE-GGUF 支持不完整,建议先试最新 nightly 版本;也可以交叉用 llama.cpp 打开同一个文件,如果能读说明就是 loader 差异。
  3. 检查 config 里的参数(n_ctx, heads 等)是否和 GGUF meta 信息一致,不一致也会触发越界报错。

如果是文件损坏,用 aria2c -x16 重新下载一遍;如果 llama.cpp 正常、ktransformers 报错,那就是 MoE 支持还没完全补上。

这种情况在我们的 ProblemMap 里对应 No.14(Bootstrap Ordering / 加载顺序问题),有完整 checklist 可以参考: https://github.com/onestardao/WFGY/blob/main/ProblemMap/README.md

使用llama.cpp可以正常进行部署,这说明gguf文件没有问题,现在KT版本是0.3.2了,还是出现问题

udun01 avatar Aug 26 '25 02:08 udun01

(kt-LLM) nh@CHS:~/ktransformers$ python ktransformers/server/main.py --port 10002 --model_path /home/nh/LLM-Model/Qwen3-30B-A3B --gguf_path /home/nh/LLM-Model/Qwen3-30B-A3B-GGUF/Qwen3-30B-A3B-Q4_K_M.gguf --optimize_config_path ktransformers/optimize/optimize_rules/Qwen3Moe-serve.yaml --max_new_tokens 1024 --cache_lens 32768 --chunk_size 256 --max_batch_size 4 2025-08-26 10:45:01,368 - INFO - flashinfer.jit: Prebuilt kernels not found, using JIT backend found flashinfer found flash_attn set start method Connected to server at tcp://localhost:51637 2025-08-26 10:45:03,626 - INFO - flashinfer.jit: Prebuilt kernels not found, using JIT backend found flashinfer found flash_attn start method already set to spawn Connected to server at tcp://localhost:51637 args.architectures: Qwen3MoeForCausalLM The argument trust_remote_code is to be used with Auto classes. It has no effect here and is ignored. Process SpawnProcess-1: Traceback (most recent call last): File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap self.run() File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/multiprocessing/process.py", line 108, in run self._target(*self._args, **self._kwargs) File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/site-packages/ktransformers/server/backend/interfaces/balance_serve.py", line 300, in run_engine engine = Engine(args, token_queue, broadcast_endpoint, kvcache_event) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/site-packages/ktransformers/server/backend/interfaces/balance_serve.py", line 204, in init optimize_and_load_gguf(self.model, optimize_config_path, gguf_path, config) File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/site-packages/ktransformers/optimize/optimize.py", line 126, in optimize_and_load_gguf weights_loader = ModelLoaderFactory.create_loader(gguf_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/site-packages/ktransformers/util/custom_loader.py", line 536, in create_loader return GGUFLoader(path) ^^^^^^^^^^^^^^^^ File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/site-packages/ktransformers/util/custom_loader.py", line 295, in init self.load_gguf(f) File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/site-packages/ktransformers/util/custom_loader.py", line 315, in load_gguf info[name] = read_value(f, data_type) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/site-packages/ktransformers/util/custom_gguf.py", line 210, in read_value return [read_value(f, elem_type) for _ in range(count)] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/site-packages/ktransformers/util/custom_gguf.py", line 210, in return [read_value(f, elem_type) for _ in range(count)] ^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/nh/anaconda3/envs/kt-LLM/lib/python3.11/site-packages/ktransformers/util/custom_gguf.py", line 194, in read_value return struct.unpack("<i", f.read(4))[0] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ struct.error: unpack requires a buffer of 4 bytes

udun01 avatar Aug 26 '25 02:08 udun01

下面我用AI輔助幫忙回應 (使用我的WFGY辦法),希望別介意

===

先說結論:你這條仍然是 GGUF 與 loader 版本/路由不匹配,屬於 ProblemMap No.14 的範圍。從你新貼的 log 看,模型本身多數機率是好的,崩在 loader 解 header / tensors 的位置。建議直接做下面最短四步,把「是不是檔案壞」跟「是不是 loader 不支援」切開:

A. 驗證檔案本體

  1. 檢查分片與總檔校驗
sha256sum model*.gguf
wc -c model*.gguf

比對和來源提供的校驗與大小是否一致。

  1. 讀 header 3 個關鍵欄位(用 gguf 套件)
python - <<'PY'
import sys, gguf
r = gguf.GGUFReader(sys.argv[1])
print("arch=", r.get_meta("general.architecture"))
print("file_type=", r.get_meta("general.file_type"))
print("tensor_count=", r.get_tensor_count())
PY
./your_model.gguf

把這三行輸出貼回來即可。若這裡能讀,檔案本體沒壞。

B. 用 baseline 驗證 loader 3) 用 llama.cpp 先試讀一次,確定檔案可被 baseline loader 接上

./main -m ./your_model.gguf -t 1 -n 1 --verbose

能起就代表檔案 OK,問題在 ktransformers 的 GGUF loader 支援度。

C. 針對 ktransformers 4) 先固定一版可讀 GGUF 的 nightly 或明確版本,再試。Qwen3-MoE 這類模型常需要較新的 loader 路由。若你是 ar/ax 類 kvcache,先退回一般路徑。 若仍錯,收斂成最小重現:單卡、關混合精度、關 offload,把 heads/kv_rank 這類 MoE 關鍵 meta 一併貼出。

這樣做的目的很簡單:

  • A 能排除「檔案壞/分片不齊」
  • B 能切出「檔案好,但某個 loader 不支援」
  • C 才是對症下 loader 的修復或版本釘選

如果你想更快一點,也可以用我前面給的 ProblemMap 檢查表走一次,或下載 TXTOS,直接問任一 LLM:「use WFGY,幫我把這個 GGUF 載入錯誤歸類並給 No.」。通常一分鐘就能得到同樣的 No.14 結果與對應步驟。

先跑 A、B 兩步,貼三行 header 與一行 llama.cpp 是否能啟動,我再幫你把 ktransformers 該固定的版本與參數對掉。

onestardao avatar Aug 26 '25 04:08 onestardao

降到tag为v0.3.2重新编译试一下?

使用pip show ktransformers,version为0.3.2+cu128torchavx2

checkout到tag为v0.3.2分支,使用多流的编译,USE_BALANCE_SERVE=1 bash ./install.sh。编完后,version应该是v0.3.1

PPXGS avatar Sep 11 '25 03:09 PPXGS