# nrfunc **Repository Path**: lph993/nrfunc ## Basic Information - **Project Name**: nrfunc - **Description**: 神经区函数算法 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-19 - **Last Updated**: 2026-08-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # nrfunc —— 神经区函数算法(函数化 + 生成物) ## 一、原理 **已训练好的成熟模型**里,一层权重有 `n` 个输出单元(神经元/卷积核/注意力头), 传统上每个单元独立存 `D` 个权重(共 `n×D`)。但很多单元其实是「同类函数」—— 功能相近、参数冗余。 本库把这些单元聚成 `K` 个「区」(`K ≪ n`),**同区共用一个「区域函数」**表达: - **0 阶**:每区一个质心(均值向量),参数从 `n×D` 降到 `K×D` - **1 阶**:每区 = 均值 + 前 `r` 个主成分(截断 SVD,即低秩),另存每单元 `n×r` 投影系数 再给每个单元存一个「归属索引」(`log₂K` 位,记它属于哪一区)。于是整体的存储, 从「`n` 份独立权重」变成「`K` 份共享函数 + `n` 份归属索引」——**这就是体积压缩的来源**。 ``` 训练 ── 模型 ── 成熟模型 ──[ 函数化 + 生成物 ]──> 部署 ↑ 本库只负责这一段 ``` - **上游(不是本库的活)**:训练、模型定义、蒸馏、微调、量化感知训练(QAT)。 - **本库只做两件事**:① 函数化(把权重重新表达为区域函数 + 归属索引); ② 生成物(区域函数参数 + 索引 + 投影系数 + 量化打包 + 分片存储 + 价值对比)。 - **下游(也不是本库的活)**:把生成物接入推理/部署。生成物可经 `reconstruct()` 还原成近似权重、**当模型权重用**,但真正跑起来是下游的活。 ## 二、收益评估 函数化的收益,落在**体积 / 内存 / CPU / GPU** 四个维度(一个词:**用少量精度,换体积与内存**): | 维度 | 收益 | 一句话结论 | |------|------|-----------| | 体积 | **恒省**(8bit 量化,参数量 `n×D → K×D`) | 确定收益,最直观 | | 内存 | 有条件地省 | 只在 `K×(1+r) < n` 时净省,且看部署方式 | | CPU | 有条件地省 | 大模型(K≪n)+ Rust/GPU 才兑现,numpy 小模型可能更慢 | | GPU 显存 | 随函数部署省 | 与「内存·函数部署」同口径 | **本机真实实测(代表性数据)**: | 例子 | 层 | 体积省 | 内存·函数部署省 | 精度掉点 | |------|-----|--------|----------------|---------| | MNIST MLP | fc1 128×784 | 95.9% | 83.8% | 2.98pt | | 真实大 CNN | 最大卷积层 features.17 | 92.9% | 71.4% | 2.75pt | | 玩具 ViT | wq 64×64 | 90.5% | 62.4% | 0.71pt | > 数据口径:固定种子可复现;掉点均为「函数化后 vs 原始模型」的精度差,红线 <3pt > (库自带 `auto_alloc` 自适应分配器守住)。完整四维一表见下文「价值证明」。 ## 三、使用注意事项 1. **体积 ≠ 内存**:体积用 8bit 量化能省 90%+,但运行时内存是 float32 常驻,省得少; 且**内存省不省取决于部署方式**——`reconstruct()` 还原回稠密时内存一点不省, 只有走 `functional_forward()`(不还原、只常驻紧凑参数)才省。 2. **CPU 不是函数化的卖点**:numpy 参考实现的 1 阶前向受 Python 循环 + gather 限制, 小模型可能慢于 BLAS 稠密前向;提速只在「K≪n 的大模型 + 编译语言(Rust)/GPU」兑现。 3. **按层判断,别一刀切**:小层/首层函数化可能「内存反涨」甚至「掉点崩盘」。 用 `auto_alloc(W, eval_fn=...)` 逐层自适应(自动跳过不划算的层)最稳。 4. **处理对象是一层权重、不是整个模型**:本库处理「一层权重矩阵」这个实例无关单元; GPT 级大模型方向只做接口预留 + 理论预演,**不负责验证**(需 ≥80GB 级多卡)。 详见下文「责任边界」。 --- ## 安装 ```bash pip install nrfunc # 用户安装(发布后从包仓库安装) ``` 依赖:`numpy`、`torch`。 开发者(本地源码开发)可编辑安装: ```bash pip install -e ".[dev]" # 含 pytest / pytest-cov / mypy ``` 可选依赖(按需安装,不装也不影响函数化 + 生成物主链路): ```bash pip install -e ".[memory]" # psutil:rss_mb() 实测进程内存(不装时返回 None) ``` > `psutil` 是「软依赖」:只在 `rss_mb()` 测真实内存时需要;未安装时 `rss_mb()` > 返回 `None`(而非 0,避免误导),库其余功能完全不受影响。 ## 快速开始 ```python import numpy as np import nrfunc # 1) 你已训练好的成熟模型:抽出一层权重(任意框架,这里给 numpy) W = np.random.default_rng(0).standard_normal((256, 128)).astype(np.float32) # 2) 函数化:256 个输出单元 → 16 个区域函数(1 阶低秩,每区 8 个主成分) res = nrfunc.regionify(W, signal='G', K=16, order=1, r=8) print(f"区域数 K={res['K']},解释方差={res['explained']:.3f}") # 3) 生成物 · 价值对比(体积 / 内存;CPU/GPU 需传实测参数, # 完整四维一表落地见 examples 里的 show_value()) tbl = nrfunc.compare_value(W, res, bits_before=32, bits_after=8) print(tbl['_table']) # 4) 生成物 · 量化打包(把区域函数参数量化成可部署字节) packed, scale, n_out, n_in = nrfunc.quantize_weights(res['means'], bits=8) # 5) 生成物 · 分散存储到 4 个节点,并行读取 store = nrfunc.build_store(res, n_shards=4) params = store.region_read_many([0, 1, 2, 3]) # 6) 生成物 → 重建权重:还原成近似权重,可当模型权重用(下游再接入推理) recon = nrfunc.reconstruct(res) # (256, 128) print(f"重建权重 shape={recon.shape},保真度={res['explained']:.3f}") ``` --- ## API 参考(参数 / 用法 / 注意事项) > 下面是全部公开函数的签名与参数说明,按模块分组。注意:本库处理对象是「一层 > 权重矩阵」`(n, D)`(n=神经元/卷积核/头数,D=每单元参数量),不是整个模型。 ### 1. 函数化(core) **`regionify(rows, signal='G', K=None, order=0, r=None, iters=60, seed=0, activations=None, groups=None, assign=None, n_init=1)`** —— 分区函数化统一入口,返回 dict。 | 参数 | 说明 | |------|------| | `rows` | `(n, D)` 权重行向量(numpy 或可转 numpy 的数组) | | `signal` | `'G'` 几何(k-means)/ `'F'` 功能(余弦聚类,需 `activations`)/ `'S'` 结构(按边界切,需 `groups`) | | `K` | 分区数。省略时默认 `sqrt(n)`;`signal='S'` 由 `groups` 决定、可省略 | | `order` | `0`=质心 / `1`=低秩(默认 0) | | `r` | `order=1` 时每区主成分数,省略默认 `sqrt(D)` | | `iters` | 聚类迭代次数(G/F 用) | | `seed` | 随机种子(库内 mulberry32,固定 seed 跨平台可复现) | | `activations` | `signal='F'` 所需的 `(n, T)` 激活响应矩阵 | | `groups` | `signal='S'` 所需的 `(n,)` 结构归属(层号/头号/通道号) | | `assign` | 可选,已算好的 `(n,)` 归属,传入时跳过聚类直接构造(auto_alloc 复用) | | `n_init` | 多起点重跑次数(G/F),>1 时尝试多个确定性种子取保真最高;默认 1 | 返回 dict 关键字段:`signal`/`order`/`K`/`assign`(n,)/`n`/`D`/`explained`,以及按阶数的参数——0 阶 `centroids`(K,D);1 阶 `means`(K,D) + `components`(K,r,D) + `coeffs`(n,r)。 **`regionify_hierarchical(rows, signal='G', K_top=None, K_sub=None, order=0, r=None, iters=60, seed=0, activations=None)`** —— 多尺度树分区(先粗分大区、再区内细分),叶子区总数 ≤ `K_top×K_sub`。仅支持 `'G'/'F'`(`'S'` 结构边界本就不需层次聚类)。返回与 `regionify` 同构、可直接 `reconstruct()`。 **`reconstruct(result)`** —— 把区域函数还原成近似权重 `(n, D)`。0 阶=归属质心;1 阶=区均值+投影修正。 **`functional_forward(result, x)`** —— 函数形式前向,**不还原稠密权重**,`y = x @ W^T` 的等价计算。`x` 形状 `(..., D)`,返回 `(..., n)`。这是「为提速」的路径(共享函数只算一次),数值与先 `reconstruct()` 再前向一致(浮点误差内)。 **`regionify_transformer_block(block, signal='S', order=1, r=None)`** —— GPT 级接口预留,**不做验证**(需 ≥80GB 多卡)。普通 Transformer 请用 `regionify(signal='S', groups=...)`。 ### 2. 自适应分配器(auto_alloc) **`auto_alloc(rows, signal='G', activations=None, groups=None, budget=None, distortion=None, eval_fn=None, K_grid=None, r_grid=None, r_max=None, auto_probe=True, probe_energy=0.95, probe_cap=256, iters=60, seed=0, float_bits=32)`** —— 给一层自动挑最优 `(order,K,r)`,或判「跳过」。 | 参数 | 说明 | |------|------| | `rows` / `signal` / `activations` / `groups` | 同 `regionify` | | `budget` | 可选,函数化后字节上限;原权重已 ≤ budget 则直接跳过 | | `distortion` | 可选,失真度 = 允许的 EV 掉点上限(0~1)。给定时追加硬约束 `explained ≥ 1 - distortion`;默认 None(走省/保真加权,不设保真硬下限) | | `eval_fn` | 可选,真实精度回调 `eval_fn(result)->bool`,True=接受;这是「掉点<阈值」的**可靠**实现 | | `K_grid` / `r_grid` | 可选候选网格;默认 K 含 K=1(全局低秩)+ 2 的幂 + sqrt(n),r 由谱探测自适应生成 | | `r_max` | 可选,1 阶主成分数上限(对 r 候选截断) | | `auto_probe` | 是否启用谱探测(默认 True);关闭则 r 回退固定网格 | | `probe_energy` / `probe_cap` | 谱探测的累积能量阈值(默认 0.95)/ 规模上限(默认 256) | | `iters` / `seed` / `float_bits` | 聚类迭代 / 随机种子 / 内存口径位宽(默认 32) | 返回 dict 关键字段:`decision`(`'order1'`/`'order0'`/`'skip'`)、`result`(跳过为 None)、`order`/`K`/`r`(跳过为 None)、`saving`(节省率,正=省;跳过=0)、`explained`(重构保真度,跳过为 None)、`skipped_reason`(仅 skip 时非空)、`bytes_before`/`bytes_after`、`n_candidates`/`n_tried`、`r_est`(谱探测估计的有效维度)。 **注意**:`eval_fn` 的返回语义是「接受 = True」。你在 auto_alloc 之外自行实现掉点护栏时的写法见 `examples/python/_common.py::make_drop_guard`。 ### 3. 生成物 · 量化 / 分片 / 二进制(io) **`quantize_weights(w, bits=4)`** —— per-row 对称量化,返回 `(packed_bytes, scale, n_out, n_in)`。`bits` 仅 4/8。接受 numpy 或 torch 张量。 **`dequantize_weights(packed, scale, n_out, n_in, bits=4)`** —— 反量化回 float32。 **`packed_bytes(num_params, bits=4)`** —— 按位宽估算字节数(不含 scale 元数据)。 **`build_store(result, n_shards=1)`** —— 构建分片存储,返回 `ShardedRegionStore`。 **`ShardedRegionStore.region_read(region_id)` / `region_read_many(ids)`** —— 读区域函数参数;`region_read_many` 跨分片多线程并行。`placement()` 看分布、`load_balance()` 看负载。 **`to_bytes(result, bits=8)` / `from_bytes(data)`** —— 把整个生成物打成一段紧凑二进制字节块(**降 IO 频率与体积**),或反向解码。`bits`=8/4/32:8=INT8、4=INT4(真打包、体积再减半)、32=float32 无损。 > 字节格式:23 字节小端头(`NRFN` magic + version/order/bits/K/n/D/r)+ 区域函数参数 + assign 索引。 > `from_bytes` 只还原结构元数据+参数+assign,**不还原 signal/explained 等标量**(需自行保留)。 > 跨语言消费示例见 `examples/code/`(Go/Java/Rust/C++ 读同一段二进制)。 ### 4. 价值证明 / 基准(utils) **`size_bytes_raw(n, D, bits=32)`** —— 函数化前字节数。 **`size_bytes_regionalized(result, bits=8, index_bits_override=None)`** —— 函数化后字节数(含 1 阶投影系数与归属索引)。`index_bits_override` 可选,覆盖归属索引位宽(默认按 `ceil(log2(K))` 自动算)。 **`compare_value(rows, result, bits_before=32, bits_after=8, cpu_before_ns=None, cpu_after_ns=None, gpu_before_mb=None, gpu_after_mb=None, mem_scale=1.0)`** —— 生成四维对比表(体积/内存/CPU/GPU),返回 dict(含 `_table` 格式化字符串)。 **`cpu_time(fn, *args, iters=20, warmup=3)`** —— 同机同批 CPU 前向耗时(ns/次)。 **`gpu_memory_bytes(fn, *args, device='cuda')`** —— 实测显存(字节),无 CUDA 返回 None。 **`bench_single(fn, x, ...)` / `bench_batch(fn, batch, ...)`** —— torch 单样本延迟 / 批量吞吐(取最快轮)。 **`rss_mb()`** —— 进程常驻内存(MB),需 `psutil`(软依赖);未装返回 None。 ### 全局注意事项 1. **`assign` 数组是 int32**,`to_bytes`/`from_bytes` 里也按 int32 处理,别和权重 float 混。 2. **1 阶净省的近似充要条件是 `K×(1+r) 诚实口径(关键,别只看一张表): > - **体积 ≠ 内存**:体积用 8bit 量化能省 95.9%,但运行时内存是 float32 常驻,只省 83.8%; > 而且**内存省不省取决于部署方式**——`reconstruct()` 还原回稠密 float32 时内存一点不省, > 只有走 `functional_forward()` 函数部署(不还原、只常驻紧凑参数)才省内存。 > - **CPU 不是函数化的卖点**:numpy 参考实现里 `functional_forward` 的 1 阶小模型 > 受 Python 循环 + gather 限制,可能慢于 BLAS 稠密前向;提速只在「K≪n 的大模型 + > 编译语言(Rust)/ GPU」里兑现(见下「函数形式前向」的 0 阶 29.9× / 1 阶 1.62×)。 > - **GPU 显存**这里只给 float32 常驻口径(与「内存·函数部署」同数);GPU 上的 > 函数前向提速需 CUDA/Rust kernel,numpy 参考实现不含。`show_value()` 会给 GPU 侧 > 补上**单样本延迟 + 批量吞吐**(torch 真实 CUDA 前向,与 CPU 侧对称对齐),让 > CPU / GPU 两端的「显存 / 耗时」都能并排对比;但 GPU 函数前向的提速潜力仍需 > Rust/CUDA kernel 才兑现,此处的 torch 实测是「同一 CUDA 环境」下的可比口径。 > - 内存/显存是「存储占用」口径,不等于运行时峰值分配;CPU/GPU 只保证同机同批可比。 ## 函数形式前向:不还原权重,直接按生成物算 `reconstruct()` 是「还原成稠密权重再算」,推理速度与原始权重一致、精度有损。另一条**为提速**设计的路径是 `functional_forward()`——不还原、直接用生成物算,共享的区域函数只算一次再按归属广播,省掉 K≪n 时的重复乘: - **0 阶**:`y = (x @ centroids^T)[:, assign]` —— 只算 K 次内积,再查表广播回 n 个单元 - **1 阶**:`y = (x @ means^T)[:, assign] + Σ_j coeffs[i,j]·(components[assign[i],j] @ x)` 数值上等价于先 `reconstruct()` 再前向(浮点误差内一致)。本机实测提速(n=1024, D=512, K=16, r=8): | 阶数 | 单样本延迟 | 批量吞吐(B=1024) | 体积 | |------|-----------|-------------------|------| | 0 阶 | **29.9×** | 1.80× | 省 99.6% | | 1 阶 | **1.62×** | 0.55× | 省 96.1% | > 诚实声明:numpy 参考实现下,**0 阶提速干净兑现**;**1 阶批量未兑现理论 6.4×**(低秩修正的 gather / 小 K 矩阵乘在 numpy 里开销大)。1 阶的完整提速需在编译语言(Rust)/ GPU 里兑现——那里 gather 廉价、无 Python 开销,这正是下游部署(演算服务)该做的事。 > > 这条「Rust/GPU 才兑现」的判断已有**端到端参照**:`examples/project` 的 13.77M 检测大模型上,函数化 fc2(2048×4097 宽层、K=32 r=8)用 Rust 二进制整网前向,**CPU 快 1.93~2.65x、GPU 快 1.31~1.38x**,数值自检 9.2e-14 一致(详见 `examples/project/README.md` 的 comparison.log)。 ## 权重分散存储拓扑 区域函数权重不必集中单节点,可分散多节点分片 + IO 并行读取: - 动机①:大规模权重单节点放不下,分片是唯一出路(呼应张量/模型并行)。 - 动机②:高并发批量读取会打爆单节点权重读取吞吐,分片后 IO 并行、吞吐随分片数扩展。 - `ShardedRegionStore` 把 K 个区域函数按 `region_id` 散列到 n 个分片,`region_read_many()` 多线程并行拉取。 - `n_shards=1` 退化为「集中单节点」。 ## 嵌入式设备可行性(大模型上边缘) 本库能把「大模型上嵌入式」的**体积/内存**这堵墙撬动,但它只做「压缩 + 生成物」, 不含推理运行时——产物要能在嵌入式跑,必须有一个 C/Rust 推理 kernel 去消费它。 ### 关键:本库能撬动哪几堵墙 | 瓶颈 | 本库能否解决 | |------|-------------| | ① 存储体积(FLASH 放不下) | ✅ 能(量化 + 函数化直接压字节) | | ② 运行内存(RAM 装不下) | ✅ 部分能(函数部署不还原,条件 `K×(1+r) 诚实边界:① 上表只算权重、不含激活缓冲(嵌入式运行时激活常比权重更吃内存); > ② 掉点口径:跨规模 MLP 扫描的实测(`scale_scan.py`)+ 真实 ResNet50 的函数化验证;真实大 CNN/ResNet50 > 层函数化掉点可压到 ±0.5pt(见 aitest 结论),但小层(h=64)叠加掉点仍会到 4.16pt—— > 「装得下」与「不掉点」都取决于层冗余度; > ③ 「装得下」≠「跑得动」,推理框架与算力是另一堵更硬的墙。 ## 责任边界 - 几何分区 `G` + 0/1 阶函数:**已实证可用**。 - 功能分区 `F`:**已实现 + 已实证**——真实大 CNN(VGG 风格 6 卷积层,585,066 参数)全 6 卷积层函数化后测试准确率 99.59% → 96.84%(掉 2.75pt,固定种子可复现值)、最大卷积层体积省 92.9%(见 `examples/python/cnn_classification.py`)。 - 结构分区 `S`、多尺度树 `regionify_hierarchical`:**已实现**,均有实例 + 防回归测试(生成物可 `reconstruct()` 还原),但尚未在真实 Transformer/ViT 上验证精度,属「待验证」而非「已验证」。 - 函数形式前向 `functional_forward`:**已实现** + 防回归测试(函数前向 == 还原前向,浮点误差内一致)。0 阶单样本提速 29.9× 已实证;1 阶批量提速需 Rust/GPU 兑现(numpy 参考实现受 gather 限制)。 - 自适应分配器 `auto_alloc`:**已实现 + 已实证**(合成数据验证机制,真实精度须 `eval_fn` 兑底)——逐层搜 `(order,K,r,跳过)` + 硬约束净省 + 谱探测自适应 r 候选 + 省/保真加权目标,把反涨层转净省。 - GPT 级:`regionify_transformer_block()` 只做接口预留、不做验证(需 ≥80GB 级多卡 + ≥256GB 内存)。谁有条件谁验证。 ## 图像分类示例(examples/,真实 MNIST) 分型表的每一档,都配一个**真实图像分类(MNIST)**示例。每个示例都是「**训练 → 模型 → 函数化 → 生成物 → 部署使用**」这条完整链路的实例——MNIST 图像分类只是「训练/模型」上游环节的载体,让函数化有真实权重可切、部署有真实准确率可测。运行(需 `torch`): ```bash python examples/python/mlp_classification.py # [已验证] 小 MLP python examples/python/mnist_mlp_classification.py # [已验证] MNIST MLP python examples/python/cnn_feature_clustering.py # [未验证] 小 CNN + F 功能(接口演示) python examples/python/cnn_classification.py # [已验证] 真实大 CNN(VGG 风格 6 卷积层) python examples/python/transformer_structure_partition.py # [未验证] Transformer + S 结构 python examples/python/hierarchical_multiscale.py # [未验证] 多尺度树 python examples/python/gpt_preview.py # [未验证] GPT 级预演(纯理论) python examples/python/auto_alloc_demo.py # 自适应分配器(把反涨层转净省) python examples/python/multilayer_autoalloc.py # 参差式逐层函数化(多层 fc 各层独立决策 + 叠加测掉点) ``` 另有两个纯推算 script(不训练、无 MNIST,快速可跑): ```bash python examples/python/embedded_feasibility.py # [估算] 嵌入式:内存预算能装下多大模型(量化的体积推演) python examples/python/gpt_extrapolation.py # [推断] GPT 级收益外推(三条规律 + 跨规模扫描 + K=1 低秩证据) ``` | 示例 | 分型档 | 分区信号 | 数据集 | 状态 | |------|--------|---------|--------|------| | `mlp_classification.py` | 小 MLP | `G` 几何 | MNIST(下采样 7×7) | ✅ 已验证 | | `mnist_mlp_classification.py` | MNIST MLP | `G` 几何 | MNIST(28×28) | ✅ 已验证 | | `cnn_feature_clustering.py` | CNN | `F` 功能 | MNIST | ⚠️ 未验证(小 CNN 接口演示) | | `cnn_classification.py` | 真实大 CNN | `F` 功能 | MNIST(28×28) | ✅ 已验证 | | `transformer_structure_partition.py` | Transformer | `S` 结构 | MNIST(玩具 ViT) | ⚠️ 未验证 | | `hierarchical_multiscale.py` | 多尺度树 | `G` | MNIST(下采样) | ⚠️ 未验证 | | `gpt_preview.py` | GPT 级 | `S`+`F`+低秩 | 纯理论 | ⚠️ 预演不验证 | | `multilayer_autoalloc.py` | MNIST MLP(多层 fc) | `G` 几何(参差式逐层) | MNIST(28×28) | ✅ 已验证 | > 「已验证」= 本项目已实证精度/压缩达标;「未验证」= 接口可跑、生成物可还原、 > 但尚未在真实规模的 Transformer/GPT 上验证精度。数据集统一用 MNIST:图像分类是 > MLP/CNN/玩具 ViT 的天然试金石,能给出真实的「函数化前后准确率」对比; > CNN 档用真实大 CNN(VGG 风格 6 卷积层,测试 99.59% → 96.84%,掉 2.75pt, > 固定种子可复现值) > 证明 F 功能分区在真实规模上成立;Transformer 档用玩具 ViT(真实 MNIST 训练, > 测试 94.99% → 94.28%,掉 0.71pt)证明 S 结构分区按头切正确、生成物可还原, > 真实 ViT/LLM 精度未验证;GPT 档为纯理论预演。 > `multilayer_autoalloc.py`(参差式逐层)用 784→512→256→10 的三层 fc,各层独立 > auto_alloc(不划算的 fc3 自动 skip),整体省 81.6%、叠加掉点 2.17pt——比单层 > 函数化更能体现「逐层各取所需」与「误差累积」两条诚实口径。 ### 完整链路五阶段(每个示例都走这条) | 阶段 | 谁负责 | 在示例里的对应 | |------|--------|---------------| | ① 训练 | 上游(非库) | `_common.train_model()` 在 MNIST 上训练小网络 | | ② 模型 | 上游(非库) | 训练好的 `model`,抽出要函数化的一层权重 `W` | | ③ 函数化 | **库** | `nrfunc.regionify(W, signal=..., K=..., order=...)` | | ④ 生成物 | **库** | `show_value()`/`compare_value()` 价值四维(体积/内存/CPU/GPU)+ `quantize_weights()` 量化打包 + `build_store()` 分片存储 | | ⑤ 部署使用 | 下游(非库) | `reconstruct()` 还原权重 → 塞回模型 → 测准确率 | 库只负责 **③ 函数化 + ④ 生成物** 两段;**①② 训练/模型、⑤ 部署** 是上下游, 示例为了给出真实权重和真实准确率,把它们也一并跑通,构成「训练 → 模型 → 函数化 → 生成物 → 部署使用」的完整闭环。 ## 目录结构 ``` nrfunc/ ├── src/nrfunc/ │ ├── core/ │ │ ├── region.py # 区划分(功能区 / 旁区) │ │ ├── functionalize.py # 函数化核心(k-means / 低秩 / F/S 分型) │ │ └── auto_alloc.py # 自适应分配器(逐层搜 (order,K,r,跳过)) │ ├── io/ │ │ ├── serialize.py # 生成物 · 量化打包 │ │ └── sharding.py # 生成物 · 分散存储 │ ├── utils/ │ │ ├── benchmark.py # 性能基准 │ │ └── value.py # 价值证明四维对比 │ └── _rand.py # 确定性随机(复现) ├── tests/ └── examples/ ├── python/ │ ├── _common.py # 共享:路径引导 + MNIST 加载 + 训练/评估助手 │ ├── _run_all.py # 一键跑全部示例(UTF-8 日志落盘) │ ├── functionalize_demo.py # 端到端:函数化 → 生成物 → 重建权重(合成数据) │ ├── four_directions_demo.py # 四方向(A/B/C/D)各一实例,共用合成数据集 │ ├── functional_forward_demo.py # 函数形式前向:正确性 + 稠密 vs 函数提速 │ ├── auto_alloc_demo.py # 自适应分配器:把反涨层转净省 │ ├── multilayer_autoalloc.py # 参差式逐层函数化(多层 fc 各层独立决策 + 叠加测掉点) │ │ │ │ # ── 估算 / 推断(纯推算,无训练,快)── │ ├── embedded_feasibility.py # [估算] 嵌入式设备可行性:内存预算能装下多大模型 │ ├── gpt_extrapolation.py # [推断] GPT 级收益外推:三条规律 + 跨规模扫描 + K=1 低秩证据 │ │ │ │ # ── 图像分类示例(真实 MNIST,含训练上游 + 函数化 + 精度对比)── │ ├── mlp_classification.py # [已验证] 小 MLP(下采样 MNIST)+ G 几何 │ ├── mnist_mlp_classification.py # [已验证] MNIST MLP(784→128→64→10)+ G 几何 │ ├── cnn_feature_clustering.py # [未验证] 小 CNN + F 功能(按激活响应聚) │ ├── cnn_classification.py # [已验证] 真实大 CNN(VGG 风格 6 卷积层)+ F 功能 │ ├── transformer_structure_partition.py # [未验证] 玩具 ViT(真实 MNIST)+ S 结构(按头切) │ ├── hierarchical_multiscale.py # [未验证] 小 MLP + B 多尺度树(先粗后细) │ └── gpt_preview.py # [未验证] GPT 级 S+F+低秩 组合预演(纯理论) ├── rust/ # Rust 版前向实测(CPU 零依赖 + GPU cudarc/cuBLAS,见该目录报告) └── project/ # 多对象检测大模型端到端(传统 vs 函数化两种部署对比) ``` ## 测试 ```bash pytest tests -q ``` ## 推断:GPT 这类超大模型的收益 > 本节是**基于实测规律的外推,不是验证结论**。库内对 GPT 级只做接口预留 > (`regionify_transformer_block()`)+ 理论预演(`examples/python/gpt_preview.py`), > 真实收益需 ≥80GB 级多卡验证,本机做不到。请把它当「方向性判断」。 ### 从小模型到大模型,三条实测规律 | 规律 | 实测证据(固定种子) | |------|--------------------| | **体积省钱随冗余度上升** | 小 MLP 省 82% → 大 CNN 92.9%(最大层) → 玩具 ViT 90.5%,越大越省 | | **内存/显存靠「K≪n」才兑现** | 充要条件 `K×(1+r) 注:上表是「等宽三隐层 784→h→h→h→10」的缩放扫描,逐层 auto_alloc 用 3pt 掉点红线 > 约束单层(叠加掉点因误差累积可略超单层红线,如 h=64 的 4.16pt);窄层 h=64 掉点超 3pt > 属于「窄层扫描观察值、非达标记录」。正式示例 > `multilayer_autoalloc.py` 用的是「递减 784→512→256→10」(省 81.6%、掉 2.17pt), > 两者结构不同,数字不可直接互换。 两条清晰趋势(新版 nrfunc 下的诚实值): - **掉点在跨过某临界宽度后「断崖式收敛」**(h=128 起掉点就压进 2pt 内,h=256 起 <1.1pt、 到 h=2048 甚至 -0.06pt 精度反升),比旧版(到 h=1024 才稳在 <1.5pt)收敛得更早、更狠; - **节省率整体随宽度上升、但不再严格单调**(71.7%→85.3% 区间内小幅波动), 因为新版 auto_alloc 会为 3pt 保真红线主动牺牲一点压缩,换取掉点大幅下降—— 「省得多」与「掉得少」在宽层同时成立的判断依然成立。 这正是「fc 层极宽时,参差式函数化优势被放大」的直接证据——GPT 的 FFN 层 正是典型的极宽 fc 层,按此趋势收益只会更显著。 ### 成熟模型的直接证据:K=1 全局低秩(ResNet50) 上述规律在**真实成熟 ResNet50**上得到进一步验证(101 类花草识别,13.77M 参数): - 旧版 `auto_alloc`(K 网格缺 K=1、r 网格过窄)对 layer2~4 的 13 个卷积层**全部判 skip**(总省 0%); - 新版(谱探测 + K=1 全局低秩 + distortion 约束)**14 层全部函数化,总省 11.2%,叠加掉点 -0.44pt**(精度不降反升)。 关键启示:**成熟精炼的卷积核权重「没有几何聚类结构、只有低秩结构」**,K=1 全局低秩 (等价 PCA)才是正解。这直接支撑了「GPT 的 FFN/注意力层用 K=1 + 低秩 + 结构切分组合 函数化」的可行性——GPT 的 FFN 层同样是「成熟、无聚类、低秩」的宽层。 ### 按这三条规律外推 GPT 级 1. **体积 / 内存:收益大概率显著更高** GPT 的 FFN 层、注意力层参数规模巨大(单层 n 可达数千、D 数千),`K≪n` 天然成立、参数冗余充分。外推:体积省可能到 95%+、内存净省空间比小模型大得多。 2. **CPU:首次有「真提速」的土壤** 小模型测不出提速,是因为 K 不够小、BLAS 稠密占优;GPT 层 `K≪n`,函数前向 共享计算 + 查表广播的收益才会浮现——但**前提是 Rust/CUDA kernel 兑现**, numpy 参考实现仍会受 gather/循环拖累。 3. **掉点:分型手段能兜住,但「不验证」是硬边界** 实测里 `F` 功能分区(大 CNN 掉 2.75pt)、`S` 结构分区(玩具 ViT 掉 0.71pt) 都在 <3pt 内,且 `auto_alloc` 的 `eval_fn` 能逐层把掉点压住。理论上 GPT 级 用「S(按头/层切)+ F(功能聚类)+ FFN 低秩」组合分型,同样有机会守住红线—— 但这只是推断,**GPT 级的真实掉点没有验证**。 ### 为什么不直接给结论 - 本机 12G 显存 + 16G 内存,加载不了 GPT 级权重,**无法实测**; - GPT 的权重/激活分布、冗余结构与小模型不同,前面的规律**不能保证线性外推**; - 这正对应库的诚实边界:GPT 级「谁有条件谁验证」,本库只提供接口与理论预演。 --- 如果你有条件(≥80GB 级多卡 + 大内存),欢迎用 `regionify_transformer_block()` 的接口骨架 + 上述分型思路做真实验证,那是本节推断能否成立的最终判据。 --- > 算法逻辑由本人提出,算法推演实现由AI推断 ## License MIT