ik_llama.cpp 中 IQ1_S_R4 量化的专属校验机制:PR 191 的实现解析

发布时间:2026/10/13 10:05:52

ik_llama.cpp 中 IQ1_S_R4 量化的专属校验机制:PR 191 的实现解析 人工智能大模型推理引擎本地部署模型量化【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp点击查看免费下载本文围绕 ik_llama.cpp 仓库中 PR #191Add additional checks for iq1_s_r4 quantization的技术记录展开该 PR 针对用IQ1_S_R4量化 DeepSeek-R1 时出现问题的现象在量化与加载两个阶段增加了针对该量化类型的额外检查。结合仓库源码你可以理解IQ1_S_R4为何需要一个区别于其他 k-quants 的校验路径、这些检查具体校验什么f16 row scale 的有限性、以及如何通过llama-quantize与-vq/--validate-quants命令在实际流程中触发这些检查。一、PR #191 要解决的问题仓库中的 PR 记录 191 - Add additional checks for iq1_s_r4 quantization.md 内容非常简短其 Description 原文为Something goes wrong when quantizing DeepSeek-R1 withIQ1_S_R4(see #185), so adding additional checks in the quantization.即作者用IQ1_S_R4量化 DeepSeek-R1 时发现“某处出了问题”该记录未展开具体错误细节因此在量化流程中加入额外检查。该 PR 由ikawrakow于 2025-02-07 提交并关闭是 PR #185 的后续修复工作。PR #185 的完整记录保存在 185 - IQ1_S_R4_ better 1.5 bpw quants.md理解它是理解 #191 的前置背景。该记录说明了IQ1_S_R4的设计要点IQ1_S_R4是IQ1_S的 4 行交错4-row interleaved版本使用 1.5 bpw低于IQ1_S的 1.5625 bpw它移除了IQ1_S中的f16super-block scale改为每行一个f16scale块大小block size选用 32原因是测试模型 DeepSeek-Lite 有大量 row 尺寸不能被 256 整除的张量用IQ1_S时相当一部分张量会退化到IQ4_NL该量化当时仅支持 CPUCaveat: it is CPU only for now。#185 记录中还给出了一个真实的量化日志片段DeepSeek-R1build 3549其中可以看到 imatrix 加载与逐张量转换过程load_imatrix: imatrix datasetimatrix-training-full-3 load_imatrix: loaded 720 importance matrix entries from /mnt/sda/mradermacher_DeepSeek-R1-GGUF/imatrix.dat computed on 315 chunks main: quantizing /mnt/sda/.../opensourcerelease_DeepSeek-R1-Bf16-256x21B-F16.gguf to .../...-IQ1_S_R4.gguf as IQ1_S_R4 using 48 threads这类超大 MoE 模型正是 #191 所针对的场景量化失败或产出异常张量时如果没有任何校验手段问题会被静默地写进 GGUF 文件推理时才暴露为乱码或 NaN。#191 的意义就在于把“数据合法性检查”固化到量化器与加载器中。二、IQ1_S_R4 的存储布局为什么需要专属检查从源码结构看IQ1_S_R4的块定义在 ggml/src/ggml-common.htypedef struct { uint8_t qs[16]; uint16_t qh[4]; } block_iq1_s_r4; static_assert(sizeof(block_iq1_s_r4) 24, wrong iq1_s_r4 block size/padding);在 ggml/src/ggml.c 中该类型注册为iq1_s_r4blck_size 32。结合量化入口的实现 ggml/src/iqk/iqk_quantize.cpp可以看出其数据组织方式for (int row 0; row nrows; row 4) { ggml_half * dptr (ggml_half *)cy; auto y (block_iq1_s_r4 *)(dptr 4); ... cy 4*row_size;即每 4 行共享一个头部4 个f16数值每行一个 row scale其后是交错的量化块数据。反量化侧ggml/src/iqk/iqk_quantize.cpp 的dequantize_row_iq1_s_r4同样从头部 4 个f16恢复 4 个 row scale。这一布局决定了它的风险点整个 4 行组的数值缩放完全依赖头部这 4 个 f16 scale。如果量化时输入张量含异常值NaN/Inf或中间计算溢出max[k]会传播出非有限值写入 row scale 后该组所有行的反量化结果都会变成垃圾数据。相比之下IQ1_S依赖 256 元素块上的 f16 块 scale仓库对这类类型走的是另一套块级检查路径而IQ1_S_R4没有 super-block scale只有 row scale因此 #191 增加了按 row scale 的专属校验。三、量化阶段的检查quantize 时的断言与防护#191 中“adding additional checks in the quantization”直接体现在quantize_iq1_s_r4函数内位于 ggml/src/iqk/iqk_quantize.cpp形状断言入口即要求行数是 4 的倍数、行宽是块大小 32 的倍数不满足时立即触发断言而不是产出错误数据constexpr int kBlockSize 32; GGML_ASSERT(nrows%4 0); GGML_ASSERT(n_per_row%kBlockSize 0);全零块的特判当某个 32 元素块的平方和小于1e-14f时直接写入全零 grid 条目ind 1029并把 row scale 置 0避免对空块做无意义的码本查找if (sumx2 1e-14f) { // all zero int ind 1029; // this is the grid entry with all zeros scales[4*iblk] 0; ... }imatrix 失配防护若提供了 importance matrix 但sumwx 1e-14f权重全零、或 imatrix 非零而权重为零打印Found block with mismatching importance/model weights并回退到不使用 imatrix 的加权方式而不是让异常权重污染量化结果。中间结果的数值断言码本索引与 scale 在写入前都被约束——scale 必须非负grid index 必须落在[0, 2048)范围内GGML_ASSERT(scales[4*iblk] 0); ... GGML_ASSERT(index[i] 0 index[i] 2048);row scale 的定点化写入每行的 f16 scale 由该行所有块 scale 的最大值max[k]推导1.0625f*max[k]/15若max[k]为非有限值写入的 f16 即为 NaN/Inf——这正是加载阶段检查要捕获的目标for (int k 0; k 4; k) { dptr[k] GGML_FP32_TO_FP16(1.0625f*max[k]/15);; invd[k] max[k] ? 15/max[k] : 0.f; }四、加载阶段的检查iqk_validate_tensor 与 F16ScaleRX4量化之后仓库在模型加载路径提供了第二道防线。核心是 ggml/src/iqk/iqk_quantize.cpp 中的iqk_validate_tensor它按张量类型分发到不同检查实现。针对IQ1_S_R4与IQ1_M_R4的分支为case GGML_TYPE_IQ1_S_R4: case GGML_TYPE_IQ1_M_R4: return check_tensor_row_scalesF16ScaleRX4(tensor);其中检查用的模板定义在同文件 L11888-L11932struct F16Scale { static inline int check_row(const char * data) { float d GGML_FP16_TO_FP32(*(const ggml_half *)data); return isfinite(d) ? 0 : 1; } }; template int nr struct F16ScaleRX { static inline int check_row(const char * data) { auto d (const ggml_half *)data; int nbad 0; for (int i 0; i nr; i) { if (!isfinite(GGML_FP16_TO_FP32(d[i]))) nbad; } return nbad; } }; template typename RS bool check_tensor_row_scales(const ggml_tensor * tensor) { auto row_size ggml_row_size(tensor-type, tensor-ne[0]); int num_rows ggml_nrows(tensor); auto data (const char *)tensor-data; int nbad 0; for (int row 0; row num_rows; row) { nbad RS::check_row(data); data row_size; } if (nbad 0) { fprintf(stderr, %s: found %d NaN row scales out of %d rows in tensor %s\n, __func__, nbad, num_rows, tensor-name); return false; } return true; }F16ScaleRX4精确对应IQ1_S_R4的布局读取每 4 行组头部连续存放的 4 个 f16 row scale逐个做isfinite检查并统计坏行数量发现 NaN row scale 时按张量名输出诊断信息。作为对照单行 f16 scale 类型IQ1_BN、IQ2_KS、IQ2_KL、IQ3_KS使用F16Scale而带 256 元素 f16 块 scale 的类型IQ2_K、IQ3_K及各 R4 重打包变体走check_tensor_for_blocks_256_fp16(_repacked)路径——不同存储布局对应不同检查器这正是“为 iq1_s_r4 增加 additional checks”的落点。加载侧的调用链在 src/llama.cpp当validate_quants打开时遍历位于 host buffer 上的全部张量逐个调用iqk_validate_tensor发现任何坏张量即抛出Bad tensors in model并中止加载if (validate_quants) { int nbad 0; for (auto it : model.tensors_by_name) { if (ggml_backend_buffer_is_host(it.second-buffer)) { if (!iqk_validate_tensor(it.second)) nbad; } } if (nbad 0) { LLAMA_LOG_ERROR(Found %d bad tensors in model\n, nbad); throw std::runtime_error(Bad tensors in model); } }从源码结构看该检查只作用于 host buffer 上的张量ggml_backend_buffer_is_host判定已卸载到 GPU 的张量不参与本次校验。五、实际操作如何触发这些检查5.1 量化阶段量化本身由llama-quantize见 examples/quantize/quantize.cpp完成。#185 记录中的 DeepSeek-R1 量化日志显示其支持 imatrix 输入并逐张量打印转换目标类型如converting to iq1_s_r4 .. size 7168.00 MiB - 673.00 MiB。量化过程中第三节的断言会在输入形状非法或中间值越界时立即中断而不是生成一个“看起来正常”的 GGUF 文件。#185 记录还指出一个对 DeepSeek 系模型的重要经验默认情况下 token embedding 会使用Q2_K--token-embedding-type可覆盖记录中作者手动指定了q8_0并且attn_v_b.weight的 bpw 分配需要按模型张量命名做适配。这些属于量化 mix 配置问题与 #191 的检查机制互补检查保证“写出的数据合法”mix 配置决定“写出的数据质量”。5.2 加载阶段加载侧的开关是-vq/--validate-quants参数定义于 common/common.cppif (arg -vq || arg --validate-quants) { params.validate_quants true; return true; }其默认值与帮助文本在同文件 L3359 给出-vq, --validate-quants validate quantized data while loading the model (default: 0)因此对任意使用 iq-quants 的 GGUF 模型可以在推理前做一次全量数据体检llama-cli -m DeepSeek-R1-IQ1_S_R4.gguf -vq -p test -n 1 # 或 llama-perplexity -m DeepSeek-R1-IQ1_S_R4.gguf -vq若某个IQ1_S_R4张量的 row scale 含 NaN会看到形如check_tensor_row_scales: found N NaN row scales out of M rows in tensor blk.X.ffn_gate_exps.weight的 stderr 输出并以Bad tensors in model异常终止。此外还有一个相近但不同的参数--check-tensorscommon/common.cpp对应params.check_tensors用于校验模型张量数据二者都默认关闭按需启用即可。六、检查的适用范围与限制结合仓库证据使用这套检查时需要注意以下边界只覆盖 host buffer 张量src/llama.cpp 中对ggml_backend_buffer_is_host的过滤意味着完全 offload 到 GPU 的张量不会被-vq检查到检查的是 scale 合法性不是输出质量F16ScaleRX4只判断 row scale 是否为有限值通过检查不代表模型输出正确低 bpw 量化本身的质量问题需要 perplexity 等手段评估IQ1_S_R4当前为 CPU 量化路径#185 记录明确标注 CPU onlyCUDA 侧仅提供了 dequantize 支持见 ggml/src/ggml-cuda/convert.cu 的dequantize_block_iq1_s_r4内核PR 状态为 Closed#191 的记录状态为关闭说明该修复已并入作者分支后续版本本文所述的检查代码即当前仓库中可查到的实现形态。七、小结PR #191 虽然只是一条简短的修复记录但它指向的问题具有普遍性IQ1_S_R4这类 sub-2 bpw、4 行交错、以 f16 row scale 为唯一缩放依据的量化格式一旦 scale 出现 NaN 就会让整组行的反量化结果失效且这种损坏会随 GGUF 文件静默传播。仓库给出的解法是双层防御量化阶段在 quantize_iq1_s_r4 中用断言与特判拦截形状、码本与 scale 异常加载阶段通过 iqk_validate_tensor 的F16ScaleRX4分支对每个 host 张量做 row scale 有限性检查并由-vq/--validate-quants参数统一开启。对于在大参数 MoE 模型上使用IQ1_S_R4/IQ1_M_R4量化的开发者这套检查应当成为量化流水线的标准环节。赞分享人工智能大模型推理引擎本地部署模型量化【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp点击查看免费下载相关推荐ik_llama.cpp 的 IQ1_S_R4 量化在 NEON 上的 GEMM/GEVM 提速PR 186 源码级解析与实测数据ik_llama.cpp 的 IQ1_S_R4 量化在 NEON 上的 GEMM/GEVM 提速PR 186 源码级解析与实测数据 导读 本文以 ik_lla人工智能大模型推理引擎本地部署模型量化ik_llama.cpp CUDA 量化加速实战IQ1_S_R4 从 MMQ 内核到 DeepSeek 模型部署ik_llama.cpp CUDA 量化加速实战IQ1_S_R4 从 MMQ 内核到 DeepSeek 模型部署 本文聚焦 ik_llama.cpp 为 IQ人工智能大模型推理引擎本地部署模型量化ik_llama.cpp 量化精度修复实录用 Q8_K_128 替代 Q8_1 根治 IQ1_S_R4 / IQ1_M_R4 的 fp16 溢出ik_llama.cpp 量化精度修复实录用 Q8_K_128 替代 Q8_1 根治 IQ1_S_R4 / IQ1_M_R4 的 fp16 溢出 本文以 ik人工智能大模型推理引擎本地部署模型量化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/13 10:05:52

Vue 封装实战:从组件到 hooks,掌握变化点分离与适度抽象

1. 别急着写封装:先想清楚封装到底在解决什么问题vue 的封装大概是每个前端er工作两三年后都会开始琢磨的事。尤其是接手过一个维护了四五年的老项目,你会非常深刻地感受到一件事:代码里真正的隐患往往不是“写得烂”,而是“写得太…

2026/10/13 10:00:50

Oracle到达梦迁移实战:数据类型、SQL语法与存储过程避坑指南

1. 迁移之前,先把两边的“家底”摸清楚1.1 为什么Oracle到达梦的迁移总在“意料之外”翻车做过数据库迁移的人都有一个共识:迁移本身不难,难的是迁移之后业务跑不起来。Oracle到达梦的迁移尤其如此,因为这两套数据库虽然都支持SQL…

2026/10/13 11:11:07

用Python挖掘利率与汇率背后的宏观风险信号

利率和汇率,是宏观金融分析里绕不开的两个变量。我刚开始做固收研究那阵子,带我的前辈提过一句:搞懂利率,你才能看懂债券市场的定价逻辑;搞懂汇率,你才能想明白资金在跨市场之间为什么这样流动。这话糙&…

2026/10/13 11:11:07

Flink Checkpoint排查实战:四个Tab定位慢/失败SubTask

前阵子生产集群上一个实时报表作业的 Checkpoint 连续红了三四次,业务方已经看到分钟级延迟还在涨。我打开 Flink Web UI 的 Checkpoint 页面,第一反应是盯着 Overview 顶部的状态卡:上一次是 Failed,再上一次也是 Failed。但说实…

2026/10/13 11:11:07

跑腿平台怎么选?闪送、美团跑腿、趣来达模式与成本全对比

先问一句:你有多久没用跑腿了?说实话,我以前也总觉得这类App是“懒人专用”,跟自己没什么关系。直到有一次工作日要给客户送合同,自己实在走不开,顺手下了个闪送单,40分钟送达、回传签收照片&am…

2026/10/13 11:11:07

规范的AI论文平台梯队榜(2026 精选)

基于综合性能、学术适配度、用户口碑和功能完整性,以下是当前主流AI论文写作工具的权威排名,按综合推荐指数从高到低排列,并标注核心优势与适用场景。🏆 第一梯队:全流程学术解决方案(★★★★★&#xff0…

2026/10/13 11:11:07

C语言main函数参数解析与命令行工具开发实践

1. 主函数传参的本质与应用场景在C语言开发中,main函数作为程序入口点,其参数传递机制是每个开发者必须掌握的基础知识。很多人初学时会疑惑:为什么main函数需要参数?这些参数从哪里来?实际上,这种设计体现…

2026/10/13 11:06:06

t3code:三层代码质量门禁,让低级故障不再上线

t3code 这个名字,看起来像是某个开源项目的代号,其实是我自己内部用了快两年的代码质量管控方案代号。以前我们团队经常出现这种场景:功能开发完,本地跑一遍没问题,代码 review 也只是看看逻辑对不对,结果合…

2026/10/13 5:19:27

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/13 0:04:41

基于Triton部署YOLO目标检测:从训练脚本到线上服务

简介:这份资源面向希望将目标检测模型落地到生产环境的深度学习开发者与算法工程师,聚焦于用 Triton Inference Server 部署 YOLOv9 的完整实战方案,解决从训练权重到线上推理服务之间的工程化难题。压缩包共 16 个文件,约 886KB&…

2026/10/13 0:04:41

手把手教你云端部署Qwen-Image-2.1:从GPU选型到在线文生图服务

Qwen-Image-2.1 这个开源的图像生成模型,最近在内容创作和 AI 应用圈子里热度相当高。它属于通义 Qwen 系列里的视觉生成分支,让我眼前一亮的是它对中文长文本的理解能力——以前用那些老方案生成带中文文字的图,十个里九个是“乱码印刷体”&…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑