Files
HomeAgent/internal/memory/static_embedder_mem_test.go
JianFeeeee 68835c18db perf(memory): 静态词向量改用 float32 存储(省 ~0.65GB 常驻)
生产实测:`[static_embedder] loaded 200000 words`(zh) + `378151 words`(en) = 57.8 万词 × 300 维,
`map[string][]float64` 光向量本体就 **1.29GB**(外加 map 开销 ~0.1-0.2GB),占 homed
4.14GB RSS 的约三分之一。

源数据(fastText 文本格式)本身就是 float32 精度,用 float64 存没有任何收益:
- `words map[string][]float32` / `unkVec []float32`;
- 加载时按 `ParseFloat(..., 32)` 解析(与源精度一致);
- 相似度累加仍在 float64(`sum []float64`,读时提升),计算精度不受影响。

⇒ 向量本体 1.29GB → 0.65GB,**省 0.65GB**。(与配置侧 `#topN` 可叠加:
生产把两份 vec 各限 5 万词后,向量降到 ~0.22GB。)

防复发:`TestStaticEmbedder_VectorMemIsFloat32` 用**编译期类型断言**
(`var typed []float32 = vec`)+ 字节数断言(词数×维数×4)钉住 —— 改回 float64 会直接编译失败。

验证:`go test ./internal/memory/ ./internal/agent/core/ ./internal/nlp/` 全绿。
2026-09-13 14:09:31 +08:00

38 lines
1.2 KiB
Go
Raw 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.

package memory
import (
"testing"
"unsafe"
)
// 词向量必须用 float32 存。
//
// 这条判据是拿生产内存换来的:向量本体 = 词数 × 维数 × 每元素字节数。
// 生产配置加载了 200000(zh) + 378151(en) = 57.8 万词 × 300 维 ⇒
// float64 = 1.29GB、float32 = 0.65GB(差 0.65GB 常驻)。
// 源数据fastText 文本格式)本身就是 float32 精度,用 float64 存没有任何收益。
//
// 若有人把类型改回 float64本测试**编译失败**`var vec []float32` 的类型断言),
// 这正是想要的效果。
func TestStaticEmbedder_VectorMemIsFloat32(t *testing.T) {
e := newSynthEmbedder(t, 300)
words := 0
bytes := 0
for _, vec := range e.words {
var typed []float32 = vec // 编译期断言:存储必须是 []float32
if len(typed) != e.dim {
t.Fatalf("维度不符: %d != %d", len(typed), e.dim)
}
words++
bytes += len(typed) * int(unsafe.Sizeof(typed[0]))
}
if words == 0 {
t.Fatal("合成模型应至少加载一个词")
}
// float32每词 300×4 = 1200 字节float64 会是 2400
if want := words * e.dim * 4; bytes != want {
t.Fatalf("向量本体字节数应 %dfloat32实际 %d", want, bytes)
}
}