#pragma once #include "engine/framework/assets/tensor_source.h" #include #include #include namespace engine::assets { enum class WeightMergeMode { RankWiseF32, DeltaF32, RoundedBF16Delta, }; struct LowRankWeightUpdate { std::vector a; std::vector b; int64_t r = 0; int64_t in = 0; int64_t out = 0; }; struct KroneckerWeightUpdate { std::vector left; std::vector right; int64_t left_rows = 0; int64_t left_cols = 0; int64_t right_rows = 0; int64_t right_cols = 0; }; struct WeightUpdate { std::variant factors; float scale = 1.0F; WeightMergeMode merge_mode = WeightMergeMode::DeltaF32; }; struct WeightReplacement { std::vector shape; std::vector values; }; struct WeightAdapter { std::map updates; std::map replacements; }; struct WeightAdapterReadOptions { float strength = 1.0F; // Overrides the effective alpha/r coefficient, not the user strength. std::optional scale_override; bool require_scaling_metadata = false; }; // Reads native A/B, PEFT A/B, ComfyUI up/down, and matrix LoKr factors. // Target names remain external until bound to a model. No model names here. WeightAdapter read_weight_adapter( const std::filesystem::path & path, const WeightAdapterReadOptions & options = {}); struct WeightAdapterTarget { std::string tensor; // Slice of the adapter's output rows, for fused external projections. int64_t first_row = 0; int64_t rows = 0; }; class WeightAdapterBindings { public: // Also registers the underscore spelling used by ComfyUI/LyCORIS. void add(std::string name, std::vector targets); void add(std::string name, std::string tensor); const std::vector & resolve(const std::string & name) const; private: std::unordered_map> targets_; }; WeightAdapter bind_weight_adapter( const TensorSource & base, WeightAdapter adapter, const WeightAdapterBindings & bindings, WeightMergeMode merge_mode); // Merges on host during weight loading, then uses the existing dtype/upload API. // Inference graphs and base storage stay untouched. Replacements win over updates. // Optional caching retains one uploaded dtype per adapted weight, never its variants. std::shared_ptr make_weight_adapter_source( std::shared_ptr base, WeightAdapter adapter, std::string log_prefix = "adapter", bool cache_backend_weights = false); } // namespace engine::assets