基于第一性原理 + Anthropic 2026 J-space 论文实现的具身智慧系统。 核心架构: - ODE 动力系统 + 并行专家 + J-space 工作空间广播 - 12 个异构专家(视觉/屏幕/听觉/语言/鼠标/跨模态) - workspace 256 维 + LayerNorm + RK4 积分 自主心智(最重要的能力): - 好奇心驱动探索(内在奖励 + 世界模型) - 跨会话状态持久化(海洋不蒸发) - 自我模型(知道自己会什么不会什么) - 元学习(自适应学习率 + 策略选择) 具身 Agent(完整神经系统): - 感知层:摄像头 + 麦克风 + 屏幕 + 键盘 + 鼠标 - 大脑皮层(workspace)+ 小脑(运动控制)+ 中枢神经(门控) - 海马体(情景记忆)+ 基底神经节(动作选择) - 执行器:鼠标控制 + 键盘输出 + 音频播放 + 屏幕绘制 多模态支持: - 原生图像/音频/视频/文本/键盘/鼠标 6 种模态 - 跨平台(macOS/Windows/Linux) 外挂模块系统: - 可热插拔的外部能力(小模型/知识库/工具) - 核心心智不依赖外挂,断开后继续工作 守护进程: - 用户主动 start/stop(不自启) - 后台静默运行,持续感知学习 - 状态自动保存,跨会话继续 J-lens 可解释性: - 观测模型内部每个 ODE 子步的想法 - Directed Modulation 验证 workspace 因果作用 - Selectivity 验证(ablate workspace) 小模型蒸馏: - 接 GPT-2/Qwen 等迁移理解能力 - 蒸馏完成后小模型可断开 验证结果: - 连续序列:JSpace 胜 Flat 39.7% - 语言进化:loss 3.95→2.40 - workspace ||w||:v1 0.05 → v2 16.0 - 实时五通道感知 + 具身闭环运行
83 lines
3.1 KiB
Python
83 lines
3.1 KiB
Python
"""蒸馏训练器——把小模型理解能力迁移到 JspaceAI"""
|
||
from __future__ import annotations
|
||
import torch, torch.nn.functional as F, numpy as np
|
||
|
||
|
||
class DistillationTrainer:
|
||
"""蒸馏训练器
|
||
|
||
把小模型的理解能力迁移到 JspaceAI 编码器。
|
||
训练后编码器离线也有理解能力,小模型可以断开。
|
||
"""
|
||
|
||
def __init__(self, model_v2, encoder, texts, device='cpu'):
|
||
self.model = model_v2.to(device)
|
||
self.encoder = encoder.to(device)
|
||
self.texts = texts
|
||
self.device = device
|
||
params = list(model_v2.parameters()) + list(encoder.proj.parameters())
|
||
self.optimizer = torch.optim.Adam(params, lr=1e-3)
|
||
self.history = []
|
||
|
||
def train_step(self, text_batch):
|
||
# 1. 小模型表征(target)
|
||
target = None
|
||
if self.encoder._real_model is not None:
|
||
with torch.no_grad():
|
||
inputs = self.encoder._tokenizer(
|
||
text_batch, return_tensors="pt",
|
||
truncation=True, max_length=64, padding=True
|
||
).to(self.device)
|
||
outputs = self.encoder._model(**inputs)
|
||
target = outputs.last_hidden_state.mean(dim=1)
|
||
|
||
# 2. 编码器输出
|
||
encoded = self.encoder(text_batch)
|
||
|
||
# 3. workspace 处理
|
||
xs = encoded.unsqueeze(1) # (batch, 1, input_dim)
|
||
state = self.model.init_state(xs.shape[0], self.device)
|
||
w_out, info = self.model(xs, state)
|
||
|
||
# 4. 蒸馏 loss
|
||
if target is not None:
|
||
target_proj = self.encoder.proj(target.to(self.device)).detach()
|
||
distill_loss = F.mse_loss(encoded, target_proj)
|
||
else:
|
||
# 自监督
|
||
if encoded.shape[0] > 1:
|
||
distill_loss = F.mse_loss(encoded[:-1], encoded[1:].detach())
|
||
else:
|
||
distill_loss = torch.tensor(0.0, device=self.device)
|
||
|
||
# 5. workspace 稳定性(目标 ||w||≈1)
|
||
w_norm = info['w_norm']
|
||
stability_loss = F.mse_loss(w_norm, torch.ones_like(w_norm))
|
||
|
||
# 6. 总 loss
|
||
total_loss = distill_loss + 0.1 * stability_loss
|
||
|
||
self.optimizer.zero_grad()
|
||
total_loss.backward()
|
||
torch.nn.utils.clip_grad_norm_(self.model.parameters(), 1.0)
|
||
self.optimizer.step()
|
||
|
||
self.history.append({
|
||
'loss': total_loss.item(),
|
||
'distill': distill_loss.item(),
|
||
'stability': stability_loss.item(),
|
||
'w_norm': w_norm.mean().item(),
|
||
})
|
||
return self.history[-1]
|
||
|
||
def train(self, n_steps=100, batch_size=4, verbose=True):
|
||
for step in range(n_steps):
|
||
batch = np.random.choice(self.texts, size=min(batch_size, len(self.texts)),
|
||
replace=True).tolist()
|
||
info = self.train_step(batch)
|
||
if verbose and (step+1) % 20 == 0:
|
||
print(f" step {step+1:4d} | loss {info['loss']:.4f} | "
|
||
f"distill {info['distill']:.4f} | "
|
||
f"||w|| {info['w_norm']:.3f}")
|
||
return self.history
|