| 749 | } |
| 750 | |
| 751 | std::unique_ptr<Model> create_model(const std::string& model_folder) { |
| 752 | CACTUS_LOG_DEBUG("model", "Creating model from: " << model_folder); |
| 753 | Config config; |
| 754 | std::string config_path = model_folder + "/config.txt"; |
| 755 | |
| 756 | if (!config.from_json(config_path)) { |
| 757 | CACTUS_LOG_ERROR("model", "Failed to create model - cannot load config from: " << model_folder); |
| 758 | return nullptr; |
| 759 | } |
| 760 | |
| 761 | const bool has_vision_support = |
| 762 | config.use_image_tokens || |
| 763 | config.vision_num_layers > 0 || |
| 764 | config.vision_embed_dim > 0 || |
| 765 | config.vision_hidden_dim > 0 || |
| 766 | config.visual_tokens_per_img > 0; |
| 767 | |
| 768 | if (config.model_type == Config::ModelType::LFM2 && has_vision_support) { |
| 769 | return std::make_unique<Lfm2VlModel>(config); |
| 770 | } |
| 771 | |
| 772 | const bool has_audio_support = |
| 773 | config.audio_num_layers > 0 || |
| 774 | config.audio_hidden_dim > 0; |
| 775 | |
| 776 | if (config.model_type == Config::ModelType::GEMMA4 && (has_vision_support || has_audio_support)) { |
| 777 | return std::make_unique<Gemma4MmModel>(config); |
| 778 | } |
| 779 | |
| 780 | switch (config.model_type) { |
| 781 | case Config::ModelType::QWEN: |
| 782 | return std::make_unique<QwenModel>(config); |
| 783 | case Config::ModelType::QWEN3P5: |
| 784 | return std::make_unique<Qwen3p5Model>(config); |
| 785 | case Config::ModelType::GEMMA: |
| 786 | return std::make_unique<GemmaModel>(config); |
| 787 | case Config::ModelType::GEMMA3N: |
| 788 | return std::make_unique<GemmaModel3n>(config); |
| 789 | case Config::ModelType::LFM2: |
| 790 | if (config.num_experts > 0 && config.moe_intermediate_dim > 0 && config.num_experts_per_tok > 0) { |
| 791 | return std::make_unique<LFM2MoEModel>(config); |
| 792 | } |
| 793 | return std::make_unique<LFM2Model>(config); |
| 794 | case Config::ModelType::NOMIC: |
| 795 | return std::make_unique<NomicModel>(config); |
| 796 | case Config::ModelType::WHISPER: |
| 797 | return std::make_unique<WhisperModel>(config); |
| 798 | case Config::ModelType::MOONSHINE: |
| 799 | return std::make_unique<MoonshineModel>(config); |
| 800 | case Config::ModelType::SILERO_VAD: |
| 801 | return std::make_unique<SileroVADModel>(config); |
| 802 | case Config::ModelType::PARAKEET: |
| 803 | return std::make_unique<ParakeetModel>(config); |
| 804 | case Config::ModelType::PARAKEET_TDT: |
| 805 | return std::make_unique<ParakeetTDTModel>(config); |
| 806 | case Config::ModelType::NEEDLE: |
| 807 | return std::make_unique<NeedleModel>(config); |
| 808 | case Config::ModelType::GEMMA4: |