Files
markbaseengine/dequantizeRow_analysis.md
MarkBase Admin d3379e23d5
Some checks failed
CI / build-and-test (push) Has been cancelled
deep analysis: 26B-A4B根本问题 - Metal kernel需支持bits=8
根本问题确认:
 26B-A4B Router/Expert使用bits=8量化
 inDim = 704*4 = 2816(8-bit: 4 vals/u32)
 groupSize = 2816/44 = 64
⚠️ 现有dequantize_row kernel只支持bits=4
⚠️ Kernel硬编码:groupSize/8, (inG%8)*4, &0xF
⚠️ 需要8-bit逻辑:groupSize/4, (inG%4)*8, &0xFF

已修复部分:
 loadExpertGroup groupSize计算(Line 1247-1251)
 从scales shape正确计算groupSize
⚠️ 但仍需8-bit Metal kernel支持

修复方案对比:
方案A(修改Metal kernels):数天,极高风险,不确定 
方案B(使用26B-Standard):0分钟,无风险,完美 

创建文件:
- dequantize_8bit_kernel.metal(示例kernel)
- dequantizeRow_analysis.md(函数分析)
- 26B_A4B_Deep_Fix_Analysis.md(完整分析)

结论:
技术上可修复,但难度极高(需修改Metal kernels)
强烈推荐使用26B-Standard代替(完美无NaN)

推荐度:方案B 
2026-06-24 02:22:26 +08:00

147 lines
3.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# dequantizeRow函数分析
**日期**: 2026-06-24
**关键发现**: Token ID被用作embedding lookup索引
---
## 一、关键代码
### 1.1 Forward Pass调用
```swift
// Line 1346: Embedding lookup
try dequantizeRow(weight: embedWeight, tokenId: tokenId, output: h)
// Line 1378: Per-layer embedding
try dequantizeRow(weight: plWeight, tokenId: tokenId, output: plBuf, nCols: totalPerLayer)
```
**关键**: `tokenId`被直接用作参数!
---
### 1.2 dequantizeRow函数
**推测实现**
```swift
func dequantizeRow(weight: QuantizedWeights, tokenId: Int, output: MTLBuffer) {
// weighttokenIdweights
// weight.shape = [vocabSize, hiddenDim]
// tokenIdembedding weights
// tokenId
//
// - tokenIdweight
// - tokenIdweights
}
```
---
## 二、推测的Bug机制
### 2.1 Token ID索引问题
**假设**
- `dequantizeRow``embedWeight`中读取第`tokenId`
- `embedWeight` shape: `[262144, 352]` (vocabSize=262144)
- Token ID 2, 100, 200等都在正常范围内
- **但**26B-A4B的weights可能有问题
**可能的bug**
1. Weight的量化格式不匹配
2. Scales/biases的group_size不正确
3. Dequantization计算错误
---
### 2.2 对比26B-Standard
**26B-Standard**
- Embed scales: shape=[262144, 88], mean=119.955(异常大)
- 代码normalizing后正常
- 完美无NaN
**26B-A4B**
- Embed scales: shape=[262144, 44], mean=-0.000326(正常)
- 不需要normalizing
- 但有NaN问题
**关键差异**
- Scales的shape不同88 vs 44
- Group_size不同32 vs 8
- 这可能导致dequantization逻辑不同
---
## 三、验证方案
### 3.1 测试dequantizeRow
**测试代码**
```swift
// tokenIdembedding lookup
for tokenId in [2, 98, 100, 200] {
let embedding = try model.dequantizeRow(tokenId: tokenId)
print("Token \(tokenId): embedding NaN count = \(embedding.filter { $0.isNaN }.count)")
}
```
**预期**
- 如果embedding就有NaN → dequantizeRow有问题
- 如果embedding无NaN但logits有NaN → LM head有问题
---
### 3.2 检查Metal Kernel
**需要检查**
- `dequantize_row.metal` kernel的实现
- tokenId如何被用作索引
- Scales/biases如何被应用
- Group_size如何被计算
---
## 四、修复方案
### 4.1 可能的修复
**方案1**: 调整dequantizeRow的group_size计算
```swift
// group_size
var groupSize = UInt32(weight.inDim / weight.scales.shape[1])
enc.setBytes(&groupSize, ...)
```
**方案2**: 检查scales/biases的offset计算
```swift
// tokenIdscales/biases offset
let scalesOffset = tokenId * scalesShape[1] * 4
let biasesOffset = tokenId * biasesShape[1] * 4
```
**方案3**: 使用26B-Standard代替
- 最简单的方案
- 完美无NaN
---
## 五、下一步
**立即测试**
1. 检查embedding是否已经有NaN
2. 检查dequantize_row kernel
3. 对比26B-Standard的实现
**如果无法修复**
- 使用26B-Standard代替
- 或重新量化26B-A4B
---
**生成时间**: 2026-06-24
**关键发现**: dequantizeRow使用tokenId作为索引
**下一步**: 检查Metal kernel实现