| #ifndef NEUROFLOW_MULTIMODAL_MODEL_HPP |
| #define NEUROFLOW_MULTIMODAL_MODEL_HPP |
|
|
| #include <fstream> |
| #include <string> |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include "tensor.hpp" |
| #include "networks.hpp" |
| #include "memory.hpp" |
| #include "multimodal.hpp" |
| #include <vector> |
| #include <memory> |
| #include <unordered_map> |
|
|
| namespace neuroflow { |
|
|
| |
| |
| |
| class NeuroFlowMultiModal { |
| public: |
| |
| struct Config { |
| size_t text_dim = 512; |
| size_t image_size = 224; |
| size_t patch_size = 16; |
| size_t vision_dim = 256; |
| size_t fusion_dim = 256; |
| size_t hidden_dim = 256; |
| size_t output_dim = 10; |
| size_t memory_dim = 128; |
| size_t memory_slots = 64; |
| size_t num_layers = 2; |
| size_t num_associations = 8; |
| size_t vision_layers = 4; |
| size_t vision_heads = 8; |
| bool use_quantization = false; |
| bool use_mla = false; |
| size_t mla_latent_dim = 32; |
| }; |
| |
| Config config; |
| |
| |
| std::unique_ptr<VisionEncoder> vision_encoder; |
| std::unique_ptr<CrossModalFusion> cross_modal_fusion; |
| std::unique_ptr<MultiModalAttention> multimodal_attention; |
| |
| |
| 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; |
| |
| |
| std::shared_ptr<Linear> text_proj; |
| std::shared_ptr<LayerNorm> text_norm; |
| |
| |
| std::shared_ptr<Linear> multimodal_proj; |
| std::shared_ptr<LayerNorm> multimodal_norm; |
| |
| |
| std::shared_ptr<Linear> output_layer; |
| std::shared_ptr<LayerNorm> output_norm; |
| |
| |
| std::shared_ptr<Linear> manifold_proj1; |
| std::shared_ptr<LayerNorm> manifold_norm; |
| std::shared_ptr<Linear> manifold_proj2; |
| |
| bool training_mode; |
| |
| NeuroFlowMultiModal(const Config& cfg) : config(cfg), training_mode(false) { |
| |
| |
| vision_encoder = std::make_unique<VisionEncoder>( |
| config.image_size, config.patch_size, |
| config.vision_dim, config.vision_heads, config.vision_layers); |
| |
| cross_modal_fusion = std::make_unique<CrossModalFusion>( |
| config.text_dim, config.vision_dim, config.fusion_dim); |
| |
| multimodal_attention = std::make_unique<MultiModalAttention>( |
| config.fusion_dim, config.fusion_dim, 8); |
| |
| |
| text_proj = std::make_shared<Linear>(config.text_dim, config.hidden_dim); |
| text_norm = std::make_shared<LayerNorm>(config.hidden_dim); |
| |
| |
| multimodal_proj = std::make_shared<Linear>(config.fusion_dim, config.hidden_dim); |
| multimodal_norm = std::make_shared<LayerNorm>(config.hidden_dim); |
| |
| |
| ecn = std::make_unique<ExecutiveControlNetwork>( |
| config.hidden_dim, config.hidden_dim, config.output_dim, config.num_layers); |
| |
| dmn = std::make_unique<DefaultModeNetwork>( |
| config.memory_dim, config.hidden_dim / 2, config.num_associations); |
| |
| 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); |
| |
| if (config.use_mla) { |
| mla_cache = std::make_unique<LatentKVCache>( |
| config.hidden_dim, 8, config.mla_latent_dim, 4096); |
| } |
| |
| |
| output_layer = std::make_shared<Linear>(config.hidden_dim, config.output_dim); |
| output_norm = std::make_shared<LayerNorm>(config.output_dim); |
| |
| |
| manifold_proj1 = std::make_shared<Linear>(config.hidden_dim, config.hidden_dim); |
| manifold_norm = std::make_shared<LayerNorm>(config.hidden_dim); |
| manifold_proj2 = std::make_shared<Linear>(config.hidden_dim, 32); |
| |
| if (config.use_quantization) { |
| quantize(); |
| } |
| } |
| |
| NeuroFlowMultiModal() : NeuroFlowMultiModal(Config()) {} |
| |
| |
| struct Output { |
| Tensor output; |
| Tensor decision; |
| Tensor value; |
| Tensor saliency; |
| Tensor text_image_sim; |
| Tensor gates; |
| Tensor anomaly; |
| Tensor retrieved_mem; |
| Tensor manifold; |
| Tensor vision_feat; |
| Tensor text_feat; |
| Tensor fused_feat; |
| }; |
| |
| |
| Output forward_text(const Tensor& text_input) { |
| Output out; |
| size_t batch = text_input.shape_[0]; |
| |
| |
| Tensor h = text_proj->forward(text_input); |
| h = text_norm->forward(h); |
| |
| |
| auto sn_out = sn->forward(h); |
| auto ecn_out = ecn->forward(h); |
| |
| out.saliency = sn_out.saliency; |
| out.gates = sn_out.gates; |
| out.decision = ecn_out.decision; |
| out.value = ecn_out.value; |
| |
| |
| auto mem_out = memory->forward(h); |
| out.retrieved_mem = mem_out.retrieved; |
| |
| |
| out.output = output_layer->forward(h); |
| out.output = output_norm->forward(out.output); |
| |
| return out; |
| } |
| |
| |
| Output forward_multimodal(const Tensor& text_input, const Tensor& image_input, |
| bool consolidate = false, bool return_manifold = false) { |
| Output out; |
| size_t batch = text_input.shape_[0]; |
| |
| |
| Tensor vision_feat = vision_encoder->forward(image_input); |
| out.vision_feat = vision_feat.clone(); |
| |
| |
| auto fusion_out = cross_modal_fusion->forward(text_input, vision_feat); |
| out.text_feat = fusion_out.text_feat.clone(); |
| out.text_image_sim = fusion_out.similarity.clone(); |
| out.fused_feat = fusion_out.fused.clone(); |
| |
| |
| Tensor multimodal_h = multimodal_proj->forward(fusion_out.fused); |
| multimodal_h = multimodal_norm->forward(multimodal_h); |
| |
| |
| Tensor text_enhanced = multimodal_attention->text_attend_image( |
| text_proj->forward(text_input), vision_feat); |
| |
| |
| float* mh = multimodal_h.as_fp32(); |
| float* te = text_enhanced.as_fp32(); |
| size_t min_dim = std::min(multimodal_h.shape_[1], text_enhanced.shape_[1]); |
| for (size_t b = 0; b < batch; ++b) { |
| for (size_t d = 0; d < min_dim; ++d) { |
| mh[b * multimodal_h.shape_[1] + d] += 0.3f * te[b * text_enhanced.shape_[1] + d]; |
| } |
| } |
| |
| |
| auto sn_out = sn->forward(multimodal_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]; |
| } |
| |
| |
| auto ecn_out = ecn->forward(multimodal_h); |
| out.decision = ecn_out.decision; |
| out.value = ecn_out.value; |
| |
| |
| Tensor mem_seed = memory->encode(multimodal_h); |
| auto dmn_out = dmn->forward(mem_seed); |
| |
| |
| auto mem_out = memory->forward(multimodal_h); |
| out.retrieved_mem = mem_out.retrieved; |
| |
| if (consolidate) { |
| memory->consolidate(multimodal_h); |
| } |
| |
| |
| Tensor ecn_weighted = out.decision.clone(); |
| Tensor dmn_weighted = dmn_out.vision.reshape({batch, dmn_out.vision.shape_[1]}); |
| |
| float* eg = ecn_gate.as_fp32(); |
| float* dg = dmn_gate.as_fp32(); |
| float* ew = ecn_weighted.as_fp32(); |
| float* dw = dmn_weighted.as_fp32(); |
| |
| for (size_t i = 0; i < batch; ++i) { |
| for (size_t j = 0; j < config.output_dim && j < ecn_weighted.shape_[1]; ++j) { |
| ew[i * ecn_weighted.shape_[1] + j] *= eg[i]; |
| } |
| for (size_t j = 0; j < dmn_weighted.shape_[1]; ++j) { |
| dw[i * dmn_weighted.shape_[1] + j] *= dg[i]; |
| } |
| } |
| |
| |
| |
| Tensor combined({batch, config.hidden_dim}, QuantType::FP32); |
| float* c = combined.as_fp32(); |
| |
| |
| for (size_t b = 0; b < batch; ++b) { |
| for (size_t d = 0; d < config.hidden_dim; ++d) { |
| float val = 0; |
| if (d < out.decision.shape_[1]) { |
| val += 0.3f * ew[b * out.decision.shape_[1] + d]; |
| } |
| if (d < dmn_weighted.shape_[1]) { |
| val += 0.2f * dw[b * dmn_weighted.shape_[1] + d]; |
| } |
| if (d < out.retrieved_mem.shape_[1]) { |
| val += 0.2f * out.retrieved_mem.as_fp32()[b * out.retrieved_mem.shape_[1] + d]; |
| } |
| if (d < multimodal_h.shape_[1]) { |
| val += 0.3f * mh[b * multimodal_h.shape_[1] + d]; |
| } |
| c[b * config.hidden_dim + d] = val; |
| } |
| } |
| |
| out.output = output_layer->forward(combined); |
| out.output = output_norm->forward(out.output); |
| |
| |
| if (return_manifold) { |
| Tensor manifold_in({batch, config.hidden_dim}, QuantType::FP32); |
| float* mi = manifold_in.as_fp32(); |
| float* eh = ecn_out.hidden_states.back().as_fp32(); |
| |
| for (size_t i = 0; i < batch; ++i) { |
| for (size_t j = 0; j < config.hidden_dim && j < ecn_out.hidden_states.back().shape_[1]; ++j) { |
| mi[i * config.hidden_dim + j] = eh[i * ecn_out.hidden_states.back().shape_[1] + j]; |
| } |
| for (size_t j = ecn_out.hidden_states.back().shape_[1]; j < config.hidden_dim; ++j) { |
| mi[i * config.hidden_dim + j] = 0; |
| } |
| } |
| |
| Tensor m = manifold_proj1->forward(manifold_in); |
| m = manifold_norm->forward(m); |
| TensorOps::gelu(m); |
| out.manifold = manifold_proj2->forward(m); |
| } |
| |
| return out; |
| } |
| |
| |
| Output forward(const Tensor& text_input, const Tensor* image_input = nullptr, |
| bool consolidate = false, bool return_manifold = false) { |
| if (image_input) { |
| return forward_multimodal(text_input, *image_input, consolidate, return_manifold); |
| } else { |
| return forward_text(text_input); |
| } |
| } |
| |
| |
| Output forward_image_only(const Tensor& image_input) { |
| Output out; |
| size_t batch = image_input.shape_[0]; |
| |
| |
| Tensor vision_feat = vision_encoder->forward(image_input); |
| out.vision_feat = vision_feat.clone(); |
| |
| |
| Tensor h = multimodal_proj->forward(vision_feat); |
| h = multimodal_norm->forward(h); |
| |
| |
| auto sn_out = sn->forward(h); |
| auto ecn_out = ecn->forward(h); |
| |
| out.saliency = sn_out.saliency; |
| out.gates = sn_out.gates; |
| out.decision = ecn_out.decision; |
| out.value = ecn_out.value; |
| |
| |
| auto mem_out = memory->forward(h); |
| out.retrieved_mem = mem_out.retrieved; |
| |
| |
| out.output = output_layer->forward(h); |
| out.output = output_norm->forward(out.output); |
| |
| return out; |
| } |
| |
| |
| void set_training(bool t) { |
| training_mode = t; |
| ecn->set_training(t); |
| } |
| |
| |
| void quantize() { |
| vision_encoder->quantize(); |
| cross_modal_fusion->quantize(); |
| multimodal_attention->quantize(); |
| text_proj->quantize(); |
| multimodal_proj->quantize(); |
| output_layer->quantize(); |
| manifold_proj1->quantize(); |
| manifold_proj2->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 vision_params; |
| size_t fusion_params; |
| size_t brain_params; |
| size_t memory_bytes; |
| float quantization_ratio; |
| }; |
| |
| Stats get_stats() { |
| Stats s; |
| s.total_params = 0; |
| s.vision_params = 0; |
| s.fusion_params = 0; |
| s.brain_params = 0; |
| s.memory_bytes = 0; |
| s.quantization_ratio = 0.0f; |
| |
| auto count_linear = [&](std::shared_ptr<Linear>& l, size_t& category) { |
| s.total_params += l->weight.numel(); |
| if (l->bias.data_) s.total_params += l->bias.numel(); |
| category += l->weight.numel(); |
| s.memory_bytes += l->weight.data_size_ + l->bias.data_size_; |
| }; |
| |
| |
| count_linear(vision_encoder->patch_embed->proj, s.vision_params); |
| for (auto& l : vision_encoder->self_attn_qkv) count_linear(l, s.vision_params); |
| for (auto& l : vision_encoder->self_attn_proj) count_linear(l, s.vision_params); |
| for (auto& l : vision_encoder->mlp_fc1) count_linear(l, s.vision_params); |
| for (auto& l : vision_encoder->mlp_fc2) count_linear(l, s.vision_params); |
| count_linear(vision_encoder->output_proj, s.vision_params); |
| |
| |
| count_linear(cross_modal_fusion->text_proj, s.fusion_params); |
| count_linear(cross_modal_fusion->image_proj, s.fusion_params); |
| count_linear(cross_modal_fusion->fusion_layer, s.fusion_params); |
| |
| |
| count_linear(multimodal_attention->text_query, s.fusion_params); |
| count_linear(multimodal_attention->image_key, s.fusion_params); |
| count_linear(multimodal_attention->image_value, s.fusion_params); |
| count_linear(multimodal_attention->text_output, s.fusion_params); |
| count_linear(multimodal_attention->image_query, s.fusion_params); |
| count_linear(multimodal_attention->text_key, s.fusion_params); |
| count_linear(multimodal_attention->text_value, s.fusion_params); |
| count_linear(multimodal_attention->image_output, s.fusion_params); |
| |
| |
| count_linear(text_proj, s.brain_params); |
| count_linear(multimodal_proj, s.brain_params); |
| count_linear(output_layer, s.brain_params); |
| count_linear(manifold_proj1, s.brain_params); |
| count_linear(manifold_proj2, s.brain_params); |
| |
| for (auto& l : ecn->dlpfc_linear) count_linear(l, s.brain_params); |
| count_linear(ecn->ofc1, s.brain_params); |
| count_linear(ecn->ofc2, s.brain_params); |
| count_linear(ecn->vmpfc1, s.brain_params); |
| count_linear(ecn->vmpfc2, s.brain_params); |
| |
| count_linear(dmn->mem_encoder1, s.brain_params); |
| count_linear(dmn->mem_encoder2, s.brain_params); |
| count_linear(dmn->future_proj1, s.brain_params); |
| for (auto& [h1, h2] : dmn->association_heads) { |
| count_linear(h1, s.brain_params); |
| count_linear(h2, s.brain_params); |
| } |
| |
| count_linear(sn->saliency1, s.brain_params); |
| count_linear(sn->saliency2, s.brain_params); |
| count_linear(sn->saliency3, s.brain_params); |
| count_linear(sn->gate1, s.brain_params); |
| count_linear(sn->gate2, s.brain_params); |
| count_linear(sn->anomaly1, s.brain_params); |
| count_linear(sn->anomaly2, s.brain_params); |
| |
| count_linear(memory->encode_proj, s.brain_params); |
| count_linear(memory->retrieve_proj, s.brain_params); |
| count_linear(memory->query_proj, s.brain_params); |
| |
| s.memory_bytes += memory->memory_bank.data_size_; |
| s.total_params += memory->memory_bank.numel(); |
| |
| return s; |
| } |
| |
| |
| void save(const std::string& path) { |
| std::ofstream ofs(path, std::ios::binary); |
| if (!ofs) throw std::runtime_error("Cannot open file for save: " + path); |
| |
| |
| ofs.write("NFv1", 4); |
| |
| |
| 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); |
| }; |
| |
| |
| 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); |
| if (layer->weight_scale.data_) save_tensor(prefix + ".weight_scale", layer->weight_scale); |
| }; |
| auto save_linear_raw = [&](const std::string& prefix, const Linear& layer) { |
| save_tensor(prefix + ".weight", layer.weight); |
| if (layer.bias.data_) save_tensor(prefix + ".bias", layer.bias); |
| if (layer.weight_scale.data_) save_tensor(prefix + ".weight_scale", layer.weight_scale); |
| }; |
| |
| |
| auto save_ln = [&](const std::string& prefix, const LayerNorm& ln) { |
| save_tensor(prefix + ".weight", ln.weight); |
| save_tensor(prefix + ".bias", ln.bias); |
| }; |
| |
| |
| save_linear_raw("text_proj", *text_proj); |
| save_ln("text_norm", *text_norm); |
| save_linear_raw("output_layer", *output_layer); |
| save_ln("output_norm", *output_norm); |
| |
| |
| save_linear("ecn.dlpfc0", ecn->dlpfc_linear[0]); |
| save_linear("ecn.dlpfc1", ecn->dlpfc_linear[1]); |
| save_linear("ecn.ofc1", ecn->ofc1); |
| save_linear("ecn.ofc2", ecn->ofc2); |
| save_linear("ecn.vmpfc1", ecn->vmpfc1); |
| save_linear("ecn.vmpfc2", ecn->vmpfc2); |
| |
| 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++; |
| } |
| |
| 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); |
| |
| |
| 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); |
| |
| |
| char magic[5] = {0}; |
| ifs.read(magic, 4); |
| if (std::string(magic) != "NFv1") throw std::runtime_error("Invalid model file"); |
| |
| |
| auto load_tensor_data = [&](Tensor& t) { |
| uint32_t ndim; |
| ifs.read(reinterpret_cast<char*>(&ndim), 4); |
| std::vector<size_t> shape(ndim); |
| for (uint32_t i = 0; i < ndim; i++) { |
| uint32_t d; |
| ifs.read(reinterpret_cast<char*>(&d), 4); |
| shape[i] = d; |
| } |
| uint32_t dsize; |
| ifs.read(reinterpret_cast<char*>(&dsize), 4); |
| |
| |
| if (shape == t.shape_ && dsize == t.data_size_) { |
| ifs.read(reinterpret_cast<char*>(t.data_.get()), dsize); |
| } else if (shape != t.shape_) { |
| |
| ifs.seekg(dsize, std::ios::cur); |
| } |
| }; |
| |
| |
| while (ifs.good()) { |
| uint32_t name_len; |
| ifs.read(reinterpret_cast<char*>(&name_len), 4); |
| if (name_len == 0 || !ifs) break; |
| |
| std::string name(name_len, '\0'); |
| ifs.read(&name[0], name_len); |
| |
| |
| if (name == "text_proj.weight") load_tensor_data(text_proj->weight); |
| else if (name == "text_proj.bias") load_tensor_data(text_proj->bias); |
| else if (name == "text_norm.weight") load_tensor_data(text_norm->weight); |
| else if (name == "text_norm.bias") load_tensor_data(text_norm->bias); |
| else if (name == "output_layer.weight") load_tensor_data(output_layer->weight); |
| else if (name == "output_layer.bias") load_tensor_data(output_layer->bias); |
| else if (name == "output_norm.weight") load_tensor_data(output_norm->weight); |
| else if (name == "output_norm.bias") load_tensor_data(output_norm->bias); |
| else if (name == "ecn.dlpfc0.weight") load_tensor_data(ecn->dlpfc_linear[0]->weight); |
| else if (name == "ecn.dlpfc0.bias") load_tensor_data(ecn->dlpfc_linear[0]->bias); |
| else if (name == "ecn.dlpfc1.weight") load_tensor_data(ecn->dlpfc_linear[1]->weight); |
| else if (name == "ecn.dlpfc1.bias") load_tensor_data(ecn->dlpfc_linear[1]->bias); |
| 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); |
| 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.find("dmn.head") == 0) { |
| int idx = std::stoi(name.substr(9, name.find('.', 9) - 9)); |
| bool is_h1 = (name[name.size()-1] == '1'); |
| auto& [h1, h2] = dmn->association_heads[idx]; |
| if (is_h1) load_tensor_data(h1->weight); |
| else load_tensor_data(h2->weight); |
| } |
| 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 { |
| |
| uint32_t ndim; ifs.read(reinterpret_cast<char*>(&ndim), 4); |
| for (uint32_t i = 0; i < ndim; i++) { uint32_t d; ifs.read(reinterpret_cast<char*>(&d), 4); } |
| uint32_t dsize; ifs.read(reinterpret_cast<char*>(&dsize), 4); |
| ifs.seekg(dsize, std::ios::cur); |
| } |
| } |
| ifs.close(); |
| } |
| }; |
|
|
| |
| |
| |
| class NeuroFlowMultiModalLite : public NeuroFlowMultiModal { |
| public: |
| NeuroFlowMultiModalLite(size_t text_dim = 256, size_t image_size = 112) { |
| Config cfg; |
| cfg.text_dim = text_dim; |
| cfg.image_size = image_size; |
| cfg.patch_size = 8; |
| cfg.vision_dim = 128; |
| cfg.fusion_dim = 128; |
| 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.vision_layers = 2; |
| cfg.vision_heads = 4; |
| cfg.use_quantization = true; |
| cfg.use_mla = true; |
| cfg.mla_latent_dim = 32; |
| |
| |
| } |
| }; |
|
|
| } |
|
|
| #endif |