Buckets:
| /** | |
| * NeuroFlowModel - 主模型类 | |
| * | |
| * 整合三大网络: | |
| * 1. ExecutiveControlNetwork (ECN) | |
| * 2. DefaultModeNetwork (DMN) | |
| * 3. SalienceNetwork (SN) | |
| * | |
| * + 记忆模块 | |
| * + 神经流形分析 | |
| */ | |
| namespace neuroflow { | |
| /** | |
| * NeuroFlowModel - 类脑模块化神经网络 | |
| */ | |
| class NeuroFlowModel { | |
| public: | |
| // 配置 | |
| struct Config { | |
| size_t input_dim = 512; | |
| size_t hidden_dim = 2048; | |
| size_t output_dim = 2048; | |
| size_t memory_dim = 512; | |
| size_t memory_slots = 64; | |
| size_t num_layers = 12; | |
| size_t num_associations = 8; | |
| bool use_quantization = false; | |
| bool use_mla = false; | |
| size_t mla_latent_dim = 32; | |
| bool use_causal_lm = false; | |
| size_t vocab_size = 128000; | |
| size_t max_seq_len = 512; | |
| std::string tokenizer_path = ""; | |
| size_t causal_window_size = 64; | |
| size_t sae_k = 128; | |
| size_t ntm_memory_slots = 32; | |
| size_t fusion_bottleneck_dim = 256; | |
| size_t lm_num_attn_layers = 4; | |
| size_t lm_num_attn_heads = 8; | |
| size_t lm_n_kv_heads = 2; | |
| bool lm_use_rope = true; | |
| bool lm_use_qk_norm = true; | |
| bool lm_use_swiglu = true; | |
| bool lm_use_bridge = true; | |
| std::string lm_pooling = "last"; | |
| size_t mla_n_heads = 8; | |
| size_t mla_max_cache_len = 4096; | |
| size_t d_model = 512; | |
| }; | |
| Config config; | |
| // 输入投影 | |
| std::shared_ptr<Linear> input_proj_linear; | |
| std::shared_ptr<LayerNorm> input_proj_norm; | |
| std::shared_ptr<GELU> input_proj_gelu; | |
| // 三大核心网络 | |
| std::unique_ptr<ExecutiveControlNetwork> ecn; | |
| std::unique_ptr<DefaultModeNetwork> dmn; | |
| std::unique_ptr<SalienceNetwork> sn; | |
| // 记忆模块 | |
| std::unique_ptr<MemoryConsolidationModule> memory; | |
| std::unique_ptr<LatentKVCache> mla_cache; // 可选MLA | |
| // 流形投影 | |
| std::shared_ptr<Linear> manifold_proj1; | |
| std::shared_ptr<LayerNorm> manifold_norm; | |
| std::shared_ptr<GELU> manifold_gelu; | |
| std::shared_ptr<Linear> manifold_proj2; | |
| // 输出融合 (低秩因式分解: 15000→256→5000) | |
| std::shared_ptr<Linear> output_fusion_down; | |
| std::shared_ptr<LayerNorm> output_fusion_bottleneck_norm; | |
| std::shared_ptr<Linear> output_fusion_up; | |
| std::shared_ptr<LayerNorm> output_fusion_norm; | |
| // 训练模式 | |
| bool training_mode; | |
| NeuroFlowModel(const Config& cfg) : config(cfg), training_mode(false) { | |
| // 输入投影 | |
| input_proj_linear = std::make_shared<Linear>(config.input_dim, config.hidden_dim); | |
| input_proj_norm = std::make_shared<LayerNorm>(config.hidden_dim); | |
| input_proj_gelu = std::make_shared<GELU>(); | |
| // ECN | |
| ecn = std::make_unique<ExecutiveControlNetwork>( | |
| config.hidden_dim, config.hidden_dim, config.hidden_dim, config.num_layers); | |
| // DMN | |
| dmn = std::make_unique<DefaultModeNetwork>( | |
| config.memory_dim, config.hidden_dim / 2, config.num_associations); | |
| // SN | |
| sn = std::make_unique<SalienceNetwork>( | |
| config.hidden_dim, config.hidden_dim / 2); | |
| // 记忆 | |
| memory = std::make_unique<MemoryConsolidationModule>( | |
| config.hidden_dim, config.memory_slots, config.memory_dim); | |
| // MLA (可选) | |
| if (config.use_mla) { | |
| mla_cache = std::make_unique<LatentKVCache>( | |
| config.hidden_dim, 8, config.mla_latent_dim, 4096); | |
| } | |
| // 流形投影 | |
| size_t manifold_in = config.hidden_dim + config.hidden_dim / 2; | |
| manifold_proj1 = std::make_shared<Linear>(manifold_in, config.hidden_dim); | |
| manifold_norm = std::make_shared<LayerNorm>(config.hidden_dim); | |
| manifold_gelu = std::make_shared<GELU>(); | |
| manifold_proj2 = std::make_shared<Linear>(config.hidden_dim, 32); | |
| // 输出融合 (低秩因式分解: hidden_dim*3 -> bn -> hidden_dim) | |
| size_t fusion_in = config.hidden_dim * 3; | |
| size_t bn = config.fusion_bottleneck_dim; | |
| output_fusion_down = std::make_shared<Linear>(fusion_in, bn); | |
| output_fusion_bottleneck_norm = std::make_shared<LayerNorm>(bn); | |
| output_fusion_up = std::make_shared<Linear>(bn, config.hidden_dim); | |
| output_fusion_norm = std::make_shared<LayerNorm>(config.hidden_dim); | |
| // 量化 | |
| if (config.use_quantization) { | |
| quantize(); | |
| } | |
| } | |
| // 默认构造 | |
| NeuroFlowModel() : NeuroFlowModel(Config()) {} | |
| // 输出结构 | |
| struct Output { | |
| Tensor output; // 最终输出 | |
| Tensor decision; // ECN决策 | |
| Tensor value; // OFC价值 | |
| Tensor saliency; // SN显著性 | |
| Tensor gates; // ECN/DMN门控权重 (2-class) | |
| Tensor ecn_gate; // ECN门控 | |
| Tensor dmn_gate; // DMN门控 | |
| Tensor anomaly; // 异常评分 | |
| Tensor mem_attention; // 记忆注意力 | |
| Tensor retrieved_mem; // 检索记忆 | |
| Tensor manifold; // 流形表征 (可选) | |
| }; | |
| // 前向传播 | |
| Output forward(const Tensor& x, const Tensor* memory_input = nullptr, | |
| bool consolidate = false, bool return_manifold = false) { | |
| Output out; | |
| size_t batch = x.shape_[0]; | |
| // 输入投影 | |
| Tensor h = input_proj_linear->forward(x); | |
| h = input_proj_norm->forward(h); | |
| h = input_proj_gelu->forward(h); | |
| // SN: 显著性检测 + 门控 | |
| auto sn_out = sn->forward(h); | |
| out.saliency = sn_out.saliency; | |
| out.gates = sn_out.gates; | |
| out.anomaly = sn_out.anomaly; | |
| // 提取门控权重 | |
| float* gates = out.gates.as_fp32(); | |
| Tensor ecn_gate({batch, 1}, QuantType::FP32); | |
| Tensor dmn_gate({batch, 1}, QuantType::FP32); | |
| for (size_t i = 0; i < batch; ++i) { | |
| ecn_gate.as_fp32()[i] = gates[i * 2]; | |
| dmn_gate.as_fp32()[i] = gates[i * 2 + 1]; | |
| } | |
| out.ecn_gate = ecn_gate; | |
| out.dmn_gate = dmn_gate; | |
| // ECN: 执行推理 | |
| auto ecn_out = ecn->forward(h); | |
| out.decision = ecn_out.decision; | |
| out.value = ecn_out.value; | |
| // DMN: 默认模式网络 | |
| Tensor mem_seed; | |
| if (memory_input) { | |
| mem_seed = *memory_input; | |
| } else { | |
| mem_seed = memory->encode(h); | |
| } | |
| auto dmn_out = dmn->forward(mem_seed); | |
| // 记忆检索 | |
| auto mem_out = memory->forward(h); | |
| out.retrieved_mem = mem_out.retrieved; | |
| out.mem_attention = mem_out.attention; | |
| // 记忆巩固 (可选) | |
| if (consolidate) { | |
| memory->consolidate(h); | |
| } | |
| // 门控加权 - 创建新的张量,避免修改共享数据 | |
| Tensor ecn_weighted({batch, config.hidden_dim}, QuantType::FP32); | |
| Tensor dmn_weighted_full({batch, dmn_out.vision.shape_[1]}, QuantType::FP32); | |
| float* ew = ecn_weighted.as_fp32(); | |
| float* dw = dmn_weighted_full.as_fp32(); | |
| float* ed = out.decision.as_fp32(); | |
| float* dv = dmn_out.vision.as_fp32(); | |
| float* eg = ecn_gate.as_fp32(); | |
| float* dg = dmn_gate.as_fp32(); | |
| // ECN加权 | |
| for (size_t i = 0; i < batch; ++i) { | |
| for (size_t j = 0; j < config.hidden_dim; ++j) { | |
| ew[i * config.hidden_dim + j] = ed[i * config.hidden_dim + j] * eg[i]; | |
| } | |
| } | |
| // DMN加权 | |
| for (size_t i = 0; i < batch; ++i) { | |
| for (size_t j = 0; j < dmn_out.vision.shape_[1]; ++j) { | |
| dw[i * dmn_out.vision.shape_[1] + j] = dv[i * dmn_out.vision.shape_[1] + j] * dg[i]; | |
| } | |
| } | |
| // 只取hidden_dim部分 | |
| Tensor dmn_weighted({batch, config.hidden_dim}, QuantType::FP32); | |
| float* dwf = dmn_weighted.as_fp32(); | |
| for (size_t i = 0; i < batch; ++i) { | |
| for (size_t j = 0; j < config.hidden_dim; ++j) { | |
| if (j < dmn_out.vision.shape_[1]) { | |
| dwf[i * config.hidden_dim + j] = dw[i * dmn_out.vision.shape_[1] + j]; | |
| } else { | |
| dwf[i * config.hidden_dim + j] = 0.0f; | |
| } | |
| } | |
| } | |
| // 融合: ECN + DMN + Memory | |
| std::vector<Tensor> to_concat; | |
| to_concat.push_back(ecn_weighted); | |
| to_concat.push_back(dmn_weighted); | |
| Tensor mem_for_fusion = out.retrieved_mem.clone(); | |
| if (mem_for_fusion.shape_[1] > config.hidden_dim) { | |
| // 截取 (不是reshape) | |
| Tensor truncated({batch, config.hidden_dim}, QuantType::FP32); | |
| float* tw = truncated.as_fp32(); | |
| float* mw = mem_for_fusion.as_fp32(); | |
| for (size_t i = 0; i < batch; ++i) { | |
| for (size_t j = 0; j < config.hidden_dim; ++j) { | |
| tw[i * config.hidden_dim + j] = mw[i * mem_for_fusion.shape_[1] + j]; | |
| } | |
| } | |
| mem_for_fusion = truncated; | |
| } else if (mem_for_fusion.shape_[1] < config.hidden_dim) { | |
| // 补零 | |
| Tensor padded({batch, config.hidden_dim}, QuantType::FP32); | |
| float* p = padded.as_fp32(); | |
| float* m = mem_for_fusion.as_fp32(); | |
| memset(p, 0, padded.data_size_); | |
| for (size_t i = 0; i < batch; ++i) { | |
| for (size_t j = 0; j < mem_for_fusion.shape_[1]; ++j) { | |
| p[i * config.hidden_dim + j] = m[i * mem_for_fusion.shape_[1] + j]; | |
| } | |
| } | |
| mem_for_fusion = padded; | |
| } | |
| to_concat.push_back(mem_for_fusion); | |
| Tensor combined = TensorOps::concat(to_concat, 1); | |
| Tensor fused_bn = output_fusion_down->forward(combined); | |
| fused_bn = output_fusion_bottleneck_norm->forward(fused_bn); | |
| TensorOps::relu(fused_bn); | |
| out.output = output_fusion_up->forward(fused_bn); | |
| out.output = output_fusion_norm->forward(out.output); | |
| // 流形 (可选) | |
| if (return_manifold) { | |
| Tensor manifold_in({batch, config.hidden_dim + config.hidden_dim / 2}, QuantType::FP32); | |
| float* mi = manifold_in.as_fp32(); | |
| float* eh = ecn_out.hidden_states.back().as_fp32(); | |
| float* dl = dmn_out.latent.as_fp32(); | |
| for (size_t i = 0; i < batch; ++i) { | |
| for (size_t j = 0; j < config.hidden_dim; ++j) { | |
| mi[i * manifold_in.shape_[1] + j] = eh[i * config.hidden_dim + j]; | |
| } | |
| for (size_t j = 0; j < config.hidden_dim / 2; ++j) { | |
| mi[i * manifold_in.shape_[1] + config.hidden_dim + j] = dl[i * config.hidden_dim / 2 + j]; | |
| } | |
| } | |
| Tensor m = manifold_proj1->forward(manifold_in); | |
| m = manifold_norm->forward(m); | |
| m = manifold_gelu->forward(m); | |
| out.manifold = manifold_proj2->forward(m); | |
| } | |
| return out; | |
| } | |
| // 神经流形轨迹 | |
| std::vector<Tensor> get_manifold_trajectory(const Tensor& x, size_t steps = 10) { | |
| std::vector<Tensor> trajectory; | |
| Tensor current = x.clone(); | |
| for (size_t s = 0; s < steps; ++s) { | |
| auto out = forward(current, nullptr, false, true); | |
| trajectory.push_back(out.manifold.clone()); | |
| // 残差更新 | |
| float* c = current.as_fp32(); | |
| float* o = out.output.as_fp32(); | |
| for (size_t i = 0; i < current.shape_[0]; ++i) { | |
| size_t min_dim = std::min(current.shape_[1], out.output.shape_[1]); | |
| for (size_t j = 0; j < min_dim; ++j) { | |
| c[i * current.shape_[1] + j] += 0.1f * o[i * out.output.shape_[1] + j]; | |
| } | |
| } | |
| } | |
| return trajectory; | |
| } | |
| // 设置训练模式 | |
| void set_training(bool t) { | |
| training_mode = t; | |
| ecn->set_training(t); | |
| } | |
| // 量化 | |
| void quantize() { | |
| input_proj_linear->quantize(); | |
| manifold_proj1->quantize(); | |
| manifold_proj2->quantize(); | |
| output_fusion_down->quantize(); | |
| output_fusion_up->quantize(); | |
| ecn->quantize(); | |
| dmn->quantize(); | |
| sn->quantize(); | |
| memory->encode_proj->quantize(); | |
| memory->retrieve_proj->quantize(); | |
| memory->query_proj->quantize(); | |
| } | |
| // 获取模型统计 | |
| struct Stats { | |
| size_t total_params; | |
| size_t memory_bytes; | |
| float quantization_ratio; | |
| }; | |
| Stats get_stats() { | |
| Stats s; | |
| s.total_params = 0; | |
| s.memory_bytes = 0; | |
| s.quantization_ratio = 0.0f; | |
| // 简化统计 | |
| size_t fp32_layers = 0; | |
| size_t quant_layers = 0; | |
| // 统计各层 | |
| auto count_linear = [&](std::shared_ptr<Linear>& l) { | |
| s.total_params += l->weight.numel(); | |
| if (l->bias.data_) s.total_params += l->bias.numel(); | |
| s.memory_bytes += l->weight.data_size_ + l->bias.data_size_; | |
| if (l->quantized) quant_layers++; | |
| else fp32_layers++; | |
| }; | |
| count_linear(input_proj_linear); | |
| count_linear(manifold_proj1); | |
| count_linear(manifold_proj2); | |
| count_linear(output_fusion_down); | |
| count_linear(output_fusion_up); | |
| for (auto& l : ecn->dlpfc_linear) count_linear(l); | |
| count_linear(ecn->ofc1); | |
| count_linear(ecn->ofc2); | |
| count_linear(ecn->vmpfc1); | |
| count_linear(ecn->vmpfc2); | |
| count_linear(dmn->mem_encoder1); | |
| count_linear(dmn->mem_encoder2); | |
| count_linear(dmn->future_proj1); | |
| for (auto& [h1, h2] : dmn->association_heads) { | |
| count_linear(h1); | |
| count_linear(h2); | |
| } | |
| count_linear(sn->saliency1); | |
| count_linear(sn->saliency2); | |
| count_linear(sn->saliency3); | |
| count_linear(sn->gate1); | |
| count_linear(sn->gate2); | |
| count_linear(sn->anomaly1); | |
| count_linear(sn->anomaly2); | |
| count_linear(memory->encode_proj); | |
| count_linear(memory->retrieve_proj); | |
| count_linear(memory->query_proj); | |
| s.memory_bytes += memory->memory_bank.data_size_; | |
| s.total_params += memory->memory_bank.numel(); | |
| if (fp32_layers + quant_layers > 0) { | |
| s.quantization_ratio = static_cast<float>(quant_layers) / (fp32_layers + quant_layers); | |
| } | |
| return s; | |
| } | |
| // ========== 序列化 (NFv1 格式) ========== | |
| void save(const std::string& path) const { | |
| std::ofstream ofs(path, std::ios::binary); | |
| if (!ofs) throw std::runtime_error("Cannot open file for save: " + path); | |
| // Magic header | |
| ofs.write("NFv1", 4); | |
| // Helper: serialize a named tensor | |
| auto save_tensor = [&](const std::string& name, const Tensor& t) { | |
| uint32_t name_len = name.size(); | |
| ofs.write(reinterpret_cast<const char*>(&name_len), 4); | |
| ofs.write(name.data(), name_len); | |
| uint32_t ndim = t.shape_.size(); | |
| ofs.write(reinterpret_cast<const char*>(&ndim), 4); | |
| for (auto d : t.shape_) { | |
| uint32_t dim = d; | |
| ofs.write(reinterpret_cast<const char*>(&dim), 4); | |
| } | |
| uint32_t dsize = t.data_size_; | |
| ofs.write(reinterpret_cast<const char*>(&dsize), 4); | |
| ofs.write(reinterpret_cast<const char*>(t.data_.get()), dsize); | |
| }; | |
| // Helper: save Linear layer (shared_ptr) | |
| auto save_linear = [&](const std::string& prefix, const std::shared_ptr<Linear>& layer) { | |
| save_tensor(prefix + ".weight", layer->weight); | |
| if (layer->bias.data_) save_tensor(prefix + ".bias", layer->bias); | |
| }; | |
| // === 输入投影 === | |
| save_linear("input_proj", input_proj_linear); | |
| save_tensor("input_proj_norm.weight", input_proj_norm->weight); | |
| save_tensor("input_proj_norm.bias", input_proj_norm->bias); | |
| // === ECN === | |
| for (size_t i = 0; i < ecn->dlpfc_linear.size(); ++i) | |
| save_linear("ecn.dlpfc" + std::to_string(i), ecn->dlpfc_linear[i]); | |
| save_linear("ecn.ofc1", ecn->ofc1); | |
| save_linear("ecn.ofc2", ecn->ofc2); | |
| save_linear("ecn.vmpfc1", ecn->vmpfc1); | |
| save_linear("ecn.vmpfc2", ecn->vmpfc2); | |
| // === DMN === | |
| save_linear("dmn.mem_encoder1", dmn->mem_encoder1); | |
| save_linear("dmn.mem_encoder2", dmn->mem_encoder2); | |
| save_linear("dmn.future_proj1", dmn->future_proj1); | |
| int head_idx = 0; | |
| for (auto& [h1, h2] : dmn->association_heads) { | |
| save_linear("dmn.head" + std::to_string(head_idx) + ".1", h1); | |
| save_linear("dmn.head" + std::to_string(head_idx) + ".2", h2); | |
| head_idx++; | |
| } | |
| // === SN === | |
| save_linear("sn.saliency1", sn->saliency1); | |
| save_linear("sn.saliency2", sn->saliency2); | |
| save_linear("sn.saliency3", sn->saliency3); | |
| save_linear("sn.gate1", sn->gate1); | |
| save_linear("sn.gate2", sn->gate2); | |
| save_linear("sn.anomaly1", sn->anomaly1); | |
| save_linear("sn.anomaly2", sn->anomaly2); | |
| // === 记忆 === | |
| save_linear("memory.encode", memory->encode_proj); | |
| save_linear("memory.retrieve", memory->retrieve_proj); | |
| save_linear("memory.query_proj", memory->query_proj); | |
| save_tensor("memory.bank", memory->memory_bank); | |
| // === 流形投影 === | |
| save_linear("manifold.proj1", manifold_proj1); | |
| save_tensor("manifold.norm.weight", manifold_norm->weight); | |
| save_tensor("manifold.norm.bias", manifold_norm->bias); | |
| save_linear("manifold.proj2", manifold_proj2); | |
| // === 输出融合 === | |
| save_linear("output_fusion.down", output_fusion_down); | |
| save_tensor("output_fusion.bn_norm.weight", output_fusion_bottleneck_norm->weight); | |
| save_tensor("output_fusion.bn_norm.bias", output_fusion_bottleneck_norm->bias); | |
| save_linear("output_fusion.up", output_fusion_up); | |
| save_tensor("output_fusion.norm.weight", output_fusion_norm->weight); | |
| save_tensor("output_fusion.norm.bias", output_fusion_norm->bias); | |
| // End marker | |
| uint32_t zero = 0; | |
| ofs.write(reinterpret_cast<const char*>(&zero), 4); | |
| ofs.close(); | |
| } | |
| void load(const std::string& path) { | |
| std::ifstream ifs(path, std::ios::binary); | |
| if (!ifs) throw std::runtime_error("Cannot open file for load: " + path); | |
| // Magic header | |
| char magic[5] = {0}; | |
| ifs.read(magic, 4); | |
| if (std::string(magic) != "NFv1") throw std::runtime_error("Invalid model file"); | |
| // Helper: set tensor data from stream | |
| auto load_tensor_data = [&](Tensor& t) { | |
| uint32_t ndim, dsize; | |
| ifs.read(reinterpret_cast<char*>(&ndim), 4); | |
| std::vector<size_t> shape(ndim); | |
| for (uint32_t i = 0; i < ndim; ++i) { | |
| uint32_t dim; | |
| ifs.read(reinterpret_cast<char*>(&dim), 4); | |
| shape[i] = dim; | |
| } | |
| ifs.read(reinterpret_cast<char*>(&dsize), 4); | |
| if (t.data_size_ != dsize) { | |
| t.data_ = std::shared_ptr<uint8_t>(new uint8_t[dsize], std::default_delete<uint8_t[]>()); | |
| t.shape_ = shape; | |
| t.data_size_ = dsize; | |
| } | |
| ifs.read(reinterpret_cast<char*>(t.data_.get()), dsize); | |
| }; | |
| // Helper: load named Linear layer | |
| auto load_linear = [&](const std::shared_ptr<Linear>& layer, const std::string& suffix) { | |
| if (suffix == ".weight") load_tensor_data(layer->weight); | |
| else if (suffix == ".bias") { load_tensor_data(layer->bias); } | |
| }; | |
| while (ifs.good()) { | |
| uint32_t name_len; | |
| ifs.read(reinterpret_cast<char*>(&name_len), 4); | |
| if (name_len == 0) break; // end marker or EOF | |
| std::string name(name_len, '\0'); | |
| ifs.read(&name[0], name_len); | |
| // === 输入投影 === | |
| if (name == "input_proj.weight") load_tensor_data(input_proj_linear->weight); | |
| else if (name == "input_proj.bias") load_tensor_data(input_proj_linear->bias); | |
| else if (name == "input_proj_norm.weight") load_tensor_data(input_proj_norm->weight); | |
| else if (name == "input_proj_norm.bias") load_tensor_data(input_proj_norm->bias); | |
| // === ECN === | |
| else if (name.rfind("ecn.dlpfc", 0) == 0) { | |
| std::string suffix = name.substr(name.find('.', 4)); // e.g. ".weight" | |
| int idx = std::stoi(name.substr(9, name.find('.', 9) - 9)); | |
| load_linear(ecn->dlpfc_linear[idx], suffix); | |
| } | |
| else if (name == "ecn.ofc1.weight") load_tensor_data(ecn->ofc1->weight); | |
| else if (name == "ecn.ofc1.bias") load_tensor_data(ecn->ofc1->bias); | |
| else if (name == "ecn.ofc2.weight") load_tensor_data(ecn->ofc2->weight); | |
| else if (name == "ecn.ofc2.bias") load_tensor_data(ecn->ofc2->bias); | |
| else if (name == "ecn.vmpfc1.weight") load_tensor_data(ecn->vmpfc1->weight); | |
| else if (name == "ecn.vmpfc1.bias") load_tensor_data(ecn->vmpfc1->bias); | |
| else if (name == "ecn.vmpfc2.weight") load_tensor_data(ecn->vmpfc2->weight); | |
| else if (name == "ecn.vmpfc2.bias") load_tensor_data(ecn->vmpfc2->bias); | |
| // === DMN === | |
| else if (name == "dmn.mem_encoder1.weight") load_tensor_data(dmn->mem_encoder1->weight); | |
| else if (name == "dmn.mem_encoder1.bias") load_tensor_data(dmn->mem_encoder1->bias); | |
| else if (name == "dmn.mem_encoder2.weight") load_tensor_data(dmn->mem_encoder2->weight); | |
| else if (name == "dmn.mem_encoder2.bias") load_tensor_data(dmn->mem_encoder2->bias); | |
| else if (name == "dmn.future_proj1.weight") load_tensor_data(dmn->future_proj1->weight); | |
| else if (name == "dmn.future_proj1.bias") load_tensor_data(dmn->future_proj1->bias); | |
| else if (name.rfind("dmn.head", 0) == 0) { | |
| // dmn.head<N>.<1|2>.<weight|bias> | |
| size_t dot1 = name.find('.', 8); // after "dmn.head" | |
| int h = std::stoi(name.substr(8, dot1 - 8)); | |
| size_t dot2 = name.find('.', dot1 + 1); | |
| int which = std::stoi(name.substr(dot1 + 1, dot2 - dot1 - 1)); | |
| std::string suffix = name.substr(name.rfind('.')); | |
| auto& layer = (which == 1) ? dmn->association_heads[h].first : dmn->association_heads[h].second; | |
| load_linear(layer, suffix); | |
| } | |
| // === SN === | |
| else if (name == "sn.saliency1.weight") load_tensor_data(sn->saliency1->weight); | |
| else if (name == "sn.saliency1.bias") load_tensor_data(sn->saliency1->bias); | |
| else if (name == "sn.saliency2.weight") load_tensor_data(sn->saliency2->weight); | |
| else if (name == "sn.saliency2.bias") load_tensor_data(sn->saliency2->bias); | |
| else if (name == "sn.saliency3.weight") load_tensor_data(sn->saliency3->weight); | |
| else if (name == "sn.saliency3.bias") load_tensor_data(sn->saliency3->bias); | |
| else if (name == "sn.gate1.weight") load_tensor_data(sn->gate1->weight); | |
| else if (name == "sn.gate1.bias") load_tensor_data(sn->gate1->bias); | |
| else if (name == "sn.gate2.weight") load_tensor_data(sn->gate2->weight); | |
| else if (name == "sn.gate2.bias") load_tensor_data(sn->gate2->bias); | |
| else if (name == "sn.anomaly1.weight") load_tensor_data(sn->anomaly1->weight); | |
| else if (name == "sn.anomaly1.bias") load_tensor_data(sn->anomaly1->bias); | |
| else if (name == "sn.anomaly2.weight") load_tensor_data(sn->anomaly2->weight); | |
| else if (name == "sn.anomaly2.bias") load_tensor_data(sn->anomaly2->bias); | |
| // === 记忆 === | |
| else if (name == "memory.encode.weight") load_tensor_data(memory->encode_proj->weight); | |
| else if (name == "memory.encode.bias") load_tensor_data(memory->encode_proj->bias); | |
| else if (name == "memory.retrieve.weight") load_tensor_data(memory->retrieve_proj->weight); | |
| else if (name == "memory.retrieve.bias") load_tensor_data(memory->retrieve_proj->bias); | |
| else if (name == "memory.query_proj.weight") load_tensor_data(memory->query_proj->weight); | |
| else if (name == "memory.query_proj.bias") load_tensor_data(memory->query_proj->bias); | |
| else if (name == "memory.bank") load_tensor_data(memory->memory_bank); | |
| // === 流形投影 === | |
| else if (name == "manifold.proj1.weight") load_tensor_data(manifold_proj1->weight); | |
| else if (name == "manifold.proj1.bias") load_tensor_data(manifold_proj1->bias); | |
| else if (name == "manifold.norm.weight") load_tensor_data(manifold_norm->weight); | |
| else if (name == "manifold.norm.bias") load_tensor_data(manifold_norm->bias); | |
| else if (name == "manifold.proj2.weight") load_tensor_data(manifold_proj2->weight); | |
| else if (name == "manifold.proj2.bias") load_tensor_data(manifold_proj2->bias); | |
| // === 输出融合 === | |
| else if (name == "output_fusion.down.weight") load_tensor_data(output_fusion_down->weight); | |
| else if (name == "output_fusion.down.bias") load_tensor_data(output_fusion_down->bias); | |
| else if (name == "output_fusion.bn_norm.weight") load_tensor_data(output_fusion_bottleneck_norm->weight); | |
| else if (name == "output_fusion.bn_norm.bias") load_tensor_data(output_fusion_bottleneck_norm->bias); | |
| else if (name == "output_fusion.up.weight") load_tensor_data(output_fusion_up->weight); | |
| else if (name == "output_fusion.up.bias") load_tensor_data(output_fusion_up->bias); | |
| else if (name == "output_fusion.norm.weight") load_tensor_data(output_fusion_norm->weight); | |
| else if (name == "output_fusion.norm.bias") load_tensor_data(output_fusion_norm->bias); | |
| // Unknown layer — skip | |
| else { | |
| uint32_t ndim, dsize; | |
| ifs.read(reinterpret_cast<char*>(&ndim), 4); | |
| ifs.seekg(ndim * 4, std::ios::cur); | |
| ifs.read(reinterpret_cast<char*>(&dsize), 4); | |
| ifs.seekg(dsize, std::ios::cur); | |
| } | |
| } | |
| ifs.close(); | |
| } | |
| }; | |
| /** | |
| * NeuroFlowLite - 超轻量版 | |
| * 适合边缘设备部署 | |
| */ | |
| class NeuroFlowLite : public NeuroFlowModel { | |
| public: | |
| NeuroFlowLite(size_t input_dim = 512) : NeuroFlowModel() { | |
| Config cfg; | |
| cfg.input_dim = input_dim; | |
| cfg.hidden_dim = 128; | |
| cfg.output_dim = 10; | |
| cfg.memory_dim = 64; | |
| cfg.memory_slots = 32; | |
| cfg.num_layers = 1; | |
| cfg.num_associations = 4; | |
| cfg.use_quantization = true; | |
| cfg.use_mla = true; | |
| cfg.mla_latent_dim = 32; | |
| // 需要重新初始化... | |
| } | |
| }; | |
| } // namespace neuroflow | |
Xet Storage Details
- Size:
- 28 kB
- Xet hash:
- a3bfc86873334303dba3d46bcadd32b808a578573da313fcc8c1e74b866ec808
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.