ljsysfurry commited on
Commit
a3d7c94
·
verified ·
1 Parent(s): fc12f23

Upload agentframe_quad.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. agentframe_quad.py +477 -0
agentframe_quad.py ADDED
@@ -0,0 +1,477 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ AgentFrame 四层融合实现
3
+ =======================
4
+ 认知层 × 路由层 × 存储层 × 物理层
5
+
6
+ 设计: agentframe_four_layer_blueprint.md
7
+ 实现: numpy (可 CPU 验证), 接口兼容 torch 迁移
8
+
9
+ 层:
10
+ L1 MetaCog — 认知层: 任务分解/置信度/信息缺口
11
+ L2 LandmarkRouter — 路由层: landmark 摘要 + 分层软max + Q-Cal
12
+ L3 AbsorbedMLA — 存储层: 吸收式 MLA + 分层量化 (35.6×)
13
+ L4 KVPager — 物理层: 热/温/冷三级换页 + 预测性驱逐
14
+ """
15
+ import numpy as np
16
+ from dataclasses import dataclass, field
17
+ from typing import Optional, Literal
18
+
19
+
20
+ # ============================================================
21
+ # L3 存储层: 吸收式 MLA + 分层量化 (核心, 自研)
22
+ # ============================================================
23
+ @dataclass
24
+ class CompressedKV:
25
+ """压缩后的 KV 块 (存储层输出, 物理层/路由层操作对象)"""
26
+ chunk_id: int
27
+ latent: np.ndarray # [576] 潜在向量 (kv_lora_rank 512 + k_pe 64)
28
+ quant_bits: int # 16/8/4
29
+ heat: float = 0.5 # 热度 (物理层)
30
+ last_access: float = 0.0 # 最后访问时间
31
+ size_bytes: int = 0 # 实际字节数
32
+
33
+
34
+ class AbsorbedMLA:
35
+ """
36
+ 吸收式 MLA: 只缓存 576 维潜在向量, 不展开 KV
37
+ 270KB → 30.4KB (8.9×) → INT8 15.2KB → INT4 7.6KB (35.6×)
38
+ """
39
+ KV_LORA_RANK = 512
40
+ K_ROPE = 64
41
+ DIM = KV_LORA_RANK + K_ROPE # 576
42
+
43
+ def __init__(self, n_layers=27, quant_bits=4, n_ch=32):
44
+ self.n_layers = n_layers
45
+ self.quant_bits = quant_bits
46
+ self.n_ch = n_ch
47
+ self.chunks = {} # chunk_id -> CompressedKV
48
+
49
+ def encode(self, hidden_states: np.ndarray) -> CompressedKV:
50
+ """压缩: [seq, d] → 潜在向量 [576]"""
51
+ # 模拟 kv_a_proj_with_mqa: 压缩到 512 + 64
52
+ if hidden_states.ndim == 2:
53
+ h = hidden_states.mean(axis=0)
54
+ else:
55
+ h = hidden_states
56
+ # 投影到 576 维 (实际是学习矩阵, 这里用确定性映射)
57
+ latent = np.tanh(h[:self.DIM] if len(h) >= self.DIM else np.pad(h, (0, self.DIM - len(h))))
58
+ return self._quantize(latent)
59
+
60
+ def _quantize(self, latent: np.ndarray) -> CompressedKV:
61
+ """per-channel 非对称量化"""
62
+ d = latent.shape[-1]
63
+ ch = d // self.n_ch
64
+ tc = latent.reshape(self.n_ch, ch)
65
+ if self.quant_bits < 16:
66
+ max_val = 2 ** self.quant_bits - 1
67
+ tmin = tc.min(axis=-1, keepdims=True)
68
+ tmax = tc.max(axis=-1, keepdims=True)
69
+ scale = (tmax - tmin) / max_val
70
+ q = np.clip(np.round((tc - tmin) / (scale + 1e-8)), 0, max_val)
71
+ deq = q * scale + tmin
72
+ bytes_per = self.quant_bits / 8
73
+ else:
74
+ deq = tc
75
+ bytes_per = 2
76
+ size = int(d * bytes_per)
77
+ kv = CompressedKV(
78
+ chunk_id=len(self.chunks),
79
+ latent=deq.reshape(-1),
80
+ quant_bits=self.quant_bits,
81
+ size_bytes=size,
82
+ )
83
+ self.chunks[kv.chunk_id] = kv
84
+ return kv
85
+
86
+ def bytes_per_token(self) -> float:
87
+ """每 token 每层字节 (27 层总)"""
88
+ per_layer = self.DIM * (self.quant_bits / 8) if self.quant_bits < 16 else self.DIM * 2
89
+ return per_layer * self.n_layers
90
+
91
+ def memory_bytes(self, seq_len: int) -> int:
92
+ """N 层总占用"""
93
+ return self.bytes_per_token() * seq_len * self.n_layers
94
+
95
+
96
+ # ============================================================
97
+ # L2 路由层: Landmark 摘要 + 分层软max + Q-Cal
98
+ # ============================================================
99
+ @dataclass
100
+ class ChunkSelection:
101
+ """路由层输出"""
102
+ chunk_ids: list
103
+ scores: list
104
+ weights: list # 分层软max 权重
105
+
106
+
107
+ class LandmarkRouter:
108
+ """
109
+ HiLS 思路: 块摘要 = Attn(q'c, Kc, Kc) 加权和 + 熵偏置
110
+ 分数 = (q̂·k'c)/√d + b'c, q̂ = q + W_up W_down h (Q-Cal)
111
+ """
112
+ def __init__(self, chunk_size=64, top_k=32, d_model=576, rank=16, seed=42):
113
+ self.chunk_size = chunk_size
114
+ self.top_k = top_k
115
+ self.d_model = d_model
116
+ rng = np.random.default_rng(seed)
117
+ # Q-Cal 低秩校准 (仅 0.6% 参数)
118
+ self.W_up = rng.normal(0, 0.02, (d_model, rank)) * 0.1
119
+ self.W_down = rng.normal(0, 0.02, (rank, d_model)) * 0.1
120
+ # landmark 可学习 query (每层共享一个, 简化)
121
+ self.landmark_q = rng.normal(0, 0.1, d_model)
122
+
123
+ def build_summary(self, chunk_latents: np.ndarray) -> tuple:
124
+ """
125
+ 块摘要: k'c = Σ p_j k_j (注意力加权和)
126
+ b'c = -Σ p_j log p_j (熵偏置)
127
+ """
128
+ # 用 landmark query 对块内 latent 打分
129
+ scores = self.landmark_q @ chunk_latents.T / np.sqrt(self.d_model)
130
+ p = np.exp(scores - scores.max())
131
+ p /= p.sum()
132
+ k_prime = p @ chunk_latents # 加权和 → 块摘要
133
+ entropy = -(p * np.log(p + 1e-9)).sum() # 熵偏置
134
+ return k_prime, entropy
135
+
136
+ def q_calibrate(self, query: np.ndarray, hidden: np.ndarray) -> np.ndarray:
137
+ """低秩校准: q̂ = q + W_up W_down h"""
138
+ delta = self.W_up @ (self.W_down @ hidden)
139
+ return query + delta
140
+
141
+ def route(self, query: np.ndarray, hidden: np.ndarray,
142
+ chunk_summaries: dict) -> ChunkSelection:
143
+ """
144
+ 打分 + top-K:
145
+ ŝ_i,c = (q̂ᵢ·k'c)/√d + b'c
146
+ """
147
+ q_hat = self.q_calibrate(query, hidden)
148
+ scores = {}
149
+ for cid, (k_prime, bias) in chunk_summaries.items():
150
+ s = q_hat @ k_prime / np.sqrt(self.d_model) + bias
151
+ scores[cid] = s
152
+
153
+ # top-K
154
+ ranked = sorted(scores.items(), key=lambda x: -x[1])
155
+ selected = ranked[:self.top_k]
156
+
157
+ # 分层软max: 分数标准化防饱和
158
+ raw = np.array([s for _, s in selected])
159
+ # z-score 标准化 + 温度
160
+ if raw.std() > 1e-8:
161
+ norm = (raw - raw.mean()) / (raw.std() + 1e-8)
162
+ else:
163
+ norm = raw - raw.mean()
164
+ exp_s = np.exp(norm)
165
+ weights = exp_s / exp_s.sum()
166
+
167
+ return ChunkSelection(
168
+ chunk_ids=[cid for cid, _ in selected],
169
+ scores=[s for _, s in selected],
170
+ weights=weights.tolist(),
171
+ )
172
+
173
+ def gqa_group_select(self, group_scores: np.ndarray) -> list:
174
+ """GQA 组内 max 聚合 (任一头重要即选中)"""
175
+ group_max = np.max(group_scores, axis=0)
176
+ return np.argsort(group_max)[-self.top_k:].tolist()
177
+
178
+
179
+ # ============================================================
180
+ # L4 物理层: KV 换页 + 预测性驱逐
181
+ # ============================================================
182
+ class KVPager:
183
+ """
184
+ 三级存储: 显存(热) / 内存(温) / 磁盘(冷, mmap)
185
+ 预测性驱逐: 注意力衰减 + 访问频率 + 语义相关
186
+ """
187
+ def __init__(self, vram_limit_mb=10240, ram_limit_mb=32768):
188
+ self.vram_limit = vram_limit_mb * 1024 * 1024
189
+ self.ram_limit = ram_limit_mb * 1024 * 1024
190
+ self.vram = {} # chunk_id -> CompressedKV
191
+ self.ram = {}
192
+ self.disk = {} # 模拟 mmap
193
+ self.vram_used = 0
194
+ self.ram_used = 0
195
+ self.access_log = [] # (chunk_id, time, attention_score)
196
+
197
+ def place(self, kv: CompressedKV, now: float = 0.0):
198
+ """放置: 按热度分层"""
199
+ if kv.heat >= 0.8:
200
+ if self.vram_used + kv.size_bytes <= self.vram_limit:
201
+ self.vram[kv.chunk_id] = kv
202
+ self.vram_used += kv.size_bytes
203
+ return
204
+ kv.heat = 0.6
205
+ if kv.heat >= 0.4:
206
+ if self.ram_used + kv.size_bytes <= self.ram_limit:
207
+ self.ram[kv.chunk_id] = kv
208
+ self.ram_used += kv.size_bytes
209
+ return
210
+ self.disk[kv.chunk_id] = kv
211
+
212
+ def access(self, chunk_id: int, attention_score: float, now: float):
213
+ """访问: 更新热度 + 日志"""
214
+ self.access_log.append((chunk_id, now, attention_score))
215
+ kv = self.vram.get(chunk_id) or self.ram.get(chunk_id) or self.disk.get(chunk_id)
216
+ if kv:
217
+ kv.heat = min(1.0, kv.heat + 0.15)
218
+ kv.last_access = now
219
+ # 磁盘 → 提升
220
+ if chunk_id in self.disk and kv.heat >= 0.5:
221
+ self.disk.pop(chunk_id)
222
+ kv.heat = 0.6
223
+ self.place(kv, now)
224
+
225
+ def eviction_score(self, kv: CompressedKV, now: float) -> float:
226
+ """预测性驱逐分数 (越高越该驱逐)"""
227
+ # 注意力衰减: 最近分数越低越该走
228
+ logs = [a for cid, t, a in self.access_log if cid == kv.chunk_id]
229
+ if not logs:
230
+ return 0.5
231
+ attn_decay = 1.0 - np.mean(logs[-5:]) # 最近注意力均值
232
+ # 访问频率: 越频繁越留
233
+ freq = len(logs) / max(now, 1.0)
234
+ access_factor = min(freq * 5, 1.0)
235
+ # 时间衰减: 越久没访问越该走
236
+ time_decay = min((now - kv.last_access) / 100.0, 1.0)
237
+ return 0.5 * attn_decay + 0.3 * (1 - access_factor) + 0.2 * time_decay
238
+
239
+ def evict(self, now: float, target_layer: str = "vram"):
240
+ """驱逐: 选分数最高的换出"""
241
+ pool = self.vram if target_layer == "vram" else self.ram
242
+ if not pool:
243
+ return None
244
+ victim_id = max(pool, key=lambda cid: self.eviction_score(pool[cid], now))
245
+ victim = pool.pop(victim_id)
246
+ if target_layer == "vram":
247
+ self.vram_used -= victim.size_bytes
248
+ victim.heat = 0.5
249
+ self.place(victim, now) # 降级到 RAM/DISK
250
+ else:
251
+ self.ram_used -= victim.size_bytes
252
+ victim.heat = 0.2
253
+ self.disk[victim_id] = victim
254
+ return victim_id
255
+
256
+ def stats(self) -> dict:
257
+ return {
258
+ "vram": f"{len(self.vram)} 块 / {self.vram_used/1024/1024:.1f}MB",
259
+ "ram": f"{len(self.ram)} 块 / {self.ram_used/1024/1024:.1f}MB",
260
+ "disk": f"{len(self.disk)} 块",
261
+ }
262
+
263
+
264
+ # ============================================================
265
+ # L1 认知层: 元认知控制器
266
+ # ============================================================
267
+ @dataclass
268
+ class SubTask:
269
+ """子任务"""
270
+ id: int
271
+ name: str
272
+ info_needs: list # 需要的信息类型
273
+ confidence: float = 0.0 # 完成置信度
274
+
275
+
276
+ @dataclass
277
+ class RetrievalDirective:
278
+ """认知层 → 物理层指令"""
279
+ required_chunks: list
280
+ priority: Literal["hot", "warm", "cold"]
281
+ reason: str
282
+ confidence: float
283
+
284
+
285
+ class MetaCog:
286
+ """
287
+ 认知层: 任务分解 + 置信度追踪 + 信息缺口分析 + 记忆提升
288
+ """
289
+ def __init__(self, confidence_threshold=0.7):
290
+ self.confidence_threshold = confidence_threshold
291
+ self.task_stack = []
292
+ self.long_term = {} # 长期记忆 (key -> 摘要)
293
+ self.episodic = [] # 情景记忆
294
+ self._task_id = 0
295
+
296
+ def decompose(self, task: str) -> list[SubTask]:
297
+ """任务分解: 规则+关键词 (生产可换 LLM)"""
298
+ # 简单规则: 按句子/分号切分
299
+ parts = [p.strip() for p in task.replace(';', ';').replace('。', ';').split(';') if p.strip()]
300
+ subs = []
301
+ for p in parts:
302
+ self._task_id += 1
303
+ # 信息需求推断: 含"分析/对比/总结"等需要历史信息
304
+ needs = []
305
+ for kw, info in [("对比", "comparison"), ("分析", "method"),
306
+ ("历史", "history"), ("数据", "data"),
307
+ ("代码", "code"), ("总结", "result"),
308
+ ("稀疏", "sparse")]:
309
+ if kw in p:
310
+ needs.append(info)
311
+ if not needs:
312
+ needs = ["data"] # 默认需要数据
313
+ subs.append(SubTask(id=self._task_id, name=p, info_needs=needs))
314
+ self.task_stack = subs
315
+ return subs
316
+
317
+ def track_confidence(self, response_likelihood: float) -> float:
318
+ """置信度追踪 (0-1)"""
319
+ return response_likelihood
320
+
321
+ def analyze_gap(self, subtask: SubTask, context_keys: set) -> list:
322
+ """信息缺口: 需要但上下文没有的信息"""
323
+ gaps = [need for need in subtask.info_needs if need not in context_keys]
324
+ return gaps
325
+
326
+ def build_directive(self, subtask: SubTask, chunk_map: dict) -> RetrievalDirective:
327
+ """生成检索指令 (认知层 → 路由/物理层)"""
328
+ needed = []
329
+ for need in subtask.info_needs:
330
+ for cid, meta in chunk_map.items():
331
+ if need in meta.get("tags", []):
332
+ needed.append(cid)
333
+ return RetrievalDirective(
334
+ required_chunks=needed,
335
+ priority="hot" if len(needed) <= 3 else "warm",
336
+ reason=f"子任务 '{subtask.name}' 需要 {subtask.info_needs}",
337
+ confidence=subtask.confidence,
338
+ )
339
+
340
+ def promote(self, chunk_id: int, importance: float):
341
+ """记忆提升: 高频+重要 → 长期"""
342
+ if importance > 0.8:
343
+ self.long_term[chunk_id] = {"importance": importance, "promoted_at": len(self.episodic)}
344
+ self.episodic.append({"chunk": chunk_id, "importance": importance})
345
+
346
+
347
+ # ============================================================
348
+ # 四层编排 (端到端)
349
+ # ============================================================
350
+ class QuadLayerAgent:
351
+ """四层融合 Agent"""
352
+ def __init__(self, n_layers=27, quant_bits=4, top_k=32, seed=42):
353
+ self.metacog = MetaCog()
354
+ self.router = LandmarkRouter(top_k=top_k, seed=seed)
355
+ self.store = AbsorbedMLA(n_layers=n_layers, quant_bits=quant_bits)
356
+ self.pager = KVPager()
357
+ self.chunk_meta = {} # chunk_id -> {tags, ...}
358
+ self.summaries = {} # chunk_id -> (k_prime, bias)
359
+ self.now = 0.0
360
+
361
+ def ingest(self, text_chunks: list[dict]):
362
+ """
363
+ 摄取知识: text_chunks = [{"text": "...", "tags": ["data"]}, ...]
364
+ 每块 → 压缩为 CompressedKV → 建摘要 → 放置
365
+ """
366
+ for i, chunk in enumerate(text_chunks):
367
+ # 模拟 hidden states
368
+ h = np.random.default_rng(i).normal(0, 1, self.store.DIM)
369
+ kv = self.store.encode(h)
370
+ kv.heat = 0.9 # 新知识 = 热
371
+ self.pager.place(kv, self.now)
372
+ # 建 landmark 摘要
373
+ k_prime, bias = self.router.build_summary(kv.latent.reshape(1, -1))
374
+ self.summaries[kv.chunk_id] = (k_prime, bias)
375
+ self.chunk_meta[kv.chunk_id] = {"tags": chunk.get("tags", []), "text": chunk.get("text", "")}
376
+
377
+ def run_task(self, task: str, query: np.ndarray):
378
+ """执行任务: 认知 → 路由 → 存储 → 输出"""
379
+ print(f"\n{'='*56}")
380
+ print(f"任务: {task}")
381
+ print(f"{'='*56}")
382
+
383
+ # L1 认知: 分解
384
+ subtasks = self.metacog.decompose(task)
385
+ print(f"[认知层] 分解为 {len(subtasks)} 个子任务")
386
+
387
+ # L1 认知: 信息缺口 → 检索指令
388
+ directive = self.metacog.build_directive(subtasks[0], self.chunk_meta)
389
+ print(f"[认知层] 检索指令: 需要 {directive.required_chunks} ({directive.reason})")
390
+
391
+ # L4 物理: 预取
392
+ for cid in directive.required_chunks:
393
+ if cid in self.pager.disk:
394
+ kv = self.pager.disk.pop(cid)
395
+ kv.heat = 0.6
396
+ self.pager.place(kv, self.now)
397
+ print(f"[物理层] 预取完成 → {self.pager.stats()}")
398
+
399
+ # L2 路由: landmark 检索
400
+ selection = self.router.route(query, query, self.summaries)
401
+ print(f"[路由层] top-{len(selection.chunk_ids)} 块: {selection.chunk_ids[:5]}...")
402
+ print(f"[路由层] 权重分布: {[f'{w:.2f}' for w in selection.weights[:5]]}...")
403
+
404
+ # L4 物理: 访问更新
405
+ for cid, score in zip(selection.chunk_ids, selection.scores):
406
+ self.pager.access(cid, abs(score), self.now)
407
+ self.metacog.promote(cid, abs(score))
408
+
409
+ # L3 存储: 汇总被选中块的压缩表示
410
+ gathered = []
411
+ for cid in selection.chunk_ids:
412
+ kv = (self.pager.vram.get(cid) or self.pager.ram.get(cid) or self.pager.disk.get(cid))
413
+ if kv:
414
+ gathered.append(kv.latent)
415
+ context = np.mean(gathered, axis=0) if gathered else np.zeros(self.store.DIM)
416
+ print(f"[存储层] 聚合 {len(gathered)} 块压缩表示 (每块 {self.store.bytes_per_token():.1f}B)")
417
+
418
+ # 置信度
419
+ conf = self.metacog.track_confidence(0.85)
420
+ print(f"[认知层] 置信度: {conf:.2f}")
421
+
422
+ # 驱逐维护
423
+ if self.pager.vram_used > self.pager.vram_limit * 0.9:
424
+ victim = self.pager.evict(self.now, "vram")
425
+ print(f"[物理层] 驱逐 {victim} → 降级")
426
+
427
+ self.now += 1
428
+ return context, selection
429
+
430
+
431
+ # ============================================================
432
+ # 验证
433
+ # ============================================================
434
+ if __name__ == "__main__":
435
+ print("=" * 56)
436
+ print("AgentFrame 四层融合 — 端到端验证")
437
+ print("=" * 56)
438
+
439
+ # 创建 Agent
440
+ agent = QuadLayerAgent(n_layers=27, quant_bits=4, top_k=8)
441
+
442
+ # 注入知识库 (12 块, 带标签)
443
+ knowledge = [
444
+ {"text": "KV 缓存 270KB/token 展开存储", "tags": ["data", "comparison"]},
445
+ {"text": "吸收式 MLA 缓存 576 维潜在向量", "tags": ["data", "method"]},
446
+ {"text": "INT8 思考链误差 0.011", "tags": ["data", "comparison"]},
447
+ {"text": "INT4 工具结果误差 0.079", "tags": ["data"]},
448
+ {"text": "per-channel 非对称量化 27 倍精度", "tags": ["method"]},
449
+ {"text": "L40S 实测 138 万 token 上下文", "tags": ["data", "result", "comparison"]},
450
+ {"text": "HiLS 分层软max 端到端块选择", "tags": ["method", "sparse"]},
451
+ {"text": "landmark token 块摘要检索", "tags": ["method", "sparse"]},
452
+ {"text": "Q-Cal 低秩校准 0.6% 参数", "tags": ["method"]},
453
+ {"text": "GQA 组内 max 聚合", "tags": ["method", "sparse"]},
454
+ {"text": "KV 换页 mmap 冷存储", "tags": ["method", "paging"]},
455
+ {"text": "预测性驱逐注意力信号", "tags": ["method", "paging"]},
456
+ ]
457
+ agent.ingest(knowledge)
458
+ print(f"[存储层] 注入 {len(knowledge)} 块知识")
459
+ print(f"[存储层] 每 token 缓存: {agent.store.bytes_per_token():.1f}B (原 270KB → 35.6×)")
460
+ print(f"[物理层] 初始: {agent.pager.stats()}")
461
+
462
+ # 执行任务
463
+ rng = np.random.default_rng(0)
464
+ query = rng.normal(0, 1, 576)
465
+
466
+ agent.run_task("对比压缩方案;分析稀疏路由;总结实测数据", query)
467
+
468
+ # 容量对比
469
+ seq_len = 100_000
470
+ original = 270 * 1024 * seq_len * 27
471
+ compressed = agent.store.memory_bytes(seq_len)
472
+ print(f"\n{'='*56}")
473
+ print(f"容量对比 (100K token × 27 层):")
474
+ print(f" 原始展开: {original/1024**3:.1f} GB")
475
+ print(f" 四层后: {compressed/1024**3:.3f} GB")
476
+ print(f" 压缩比: {original/compressed:.1f}×")
477
+ print(f"{'='*56}")