-
Notifications
You must be signed in to change notification settings - Fork 3.3k
[NPU] Weight sharing with cache: Part 1 make compiled model weights WeightContext friendly #37427
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| // Copyright (C) 2018-2026 Intel Corporation | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <functional> | ||
| #include <memory> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| #include "openvino/runtime/aligned_buffer.hpp" | ||
|
|
||
| namespace ov { | ||
| class Model; | ||
| namespace op { | ||
| namespace v0 { | ||
| class Constant; | ||
| } // namespace v0 | ||
| } // namespace op | ||
| } // namespace ov | ||
|
|
||
| namespace ov { | ||
| namespace intel_npu { | ||
|
|
||
| class SharedWeightsAssigner { | ||
| public: | ||
| using SharedConstant = std::shared_ptr<ov::op::v0::Constant>; | ||
| using PartitionedConstants = std::vector<std::vector<SharedConstant>>; | ||
| using SharedSourceAndConstants = std::pair<std::shared_ptr<ov::AlignedBuffer>, std::vector<SharedConstant>>; | ||
| using SharedSourcesWithConstants = std::vector<SharedSourceAndConstants>; | ||
|
|
||
| struct Options { | ||
| std::vector<std::string> shared_device_contexts; | ||
| size_t single_weight_shared_source_size_max = 0; | ||
| bool preserve_weightless_cache_attr = true; | ||
| std::function<size_t()> source_id_generator; | ||
| }; | ||
|
|
||
| struct Statistic { | ||
| std::vector<size_t> partition_constant_counts; | ||
| size_t collected_constants_count = 0; | ||
| size_t total_shared_constant_bytes = 0; | ||
| size_t total_non_shared_constant_bytes_released = 0; | ||
|
|
||
| std::string to_string() const; | ||
| }; | ||
|
|
||
| struct CollectResult { | ||
| Statistic statistic; | ||
| PartitionedConstants partitioned_constants; | ||
| }; | ||
|
|
||
| explicit SharedWeightsAssigner(Options options); | ||
| CollectResult collect_and_partition(const std::shared_ptr<ov::Model>& model); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the API imposes two phases here: gathering and mutating The mutating phase comes separately and may be carried out in the case of it is justifiable according to the desired Statistic metrics |
||
| SharedSourcesWithConstants mutate_model_with_constant_sharing(PartitionedConstants&& partitioned_constants); | ||
|
|
||
| private: | ||
| bool constant_can_be_shared(const ov::op::v0::Constant& constant) const; | ||
|
|
||
| std::vector<SharedConstant> collect_weights_to_share(const std::shared_ptr<ov::Model>& model) const; | ||
|
|
||
| PartitionedConstants partition_constants_by_size(std::vector<SharedConstant>&& constants) const; | ||
|
|
||
| SharedSourcesWithConstants make_constant_shareable( | ||
| PartitionedConstants&& partitioned_constants) const; | ||
|
|
||
| std::shared_ptr<ov::AlignedBuffer> make_shared_source(const std::vector<SharedConstant>& partition) const; | ||
|
|
||
| size_t get_constant_aligned_size(const ov::op::v0::Constant& constant) const; | ||
|
|
||
| static size_t align_bytes(size_t bytes, size_t alignment); | ||
|
|
||
| std::vector<std::string> m_shared_device_contexts; | ||
| std::function<size_t()> m_source_id_generator; | ||
| bool m_preserve_weightless_cache_attr = true; | ||
| size_t m_min_relocate_bytes = 0; | ||
| size_t m_single_weight_shared_source_size_max = 0; | ||
| }; | ||
|
|
||
| } // namespace intel_npu | ||
| } // namespace ov | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
|
|
||
| #include "compiled_model.hpp" | ||
| #include "npuw_transformations/kv_axes_position.hpp" | ||
| #include "openvino/core/weight_sharing_util.hpp" | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not needed right now |
||
|
|
||
| namespace ov { | ||
| namespace test { | ||
|
|
@@ -168,7 +169,14 @@ class LLMCompiledModel : public ov::npuw::ICompiledModel { | |
| const std::shared_ptr<const ov::IPlugin>& plugin, | ||
| const ov::AnyMap& generate_config); | ||
|
|
||
| // Relocate page-aligned constants into shared cross-device memory if SHARED_WEIGHTS is set. | ||
| void assign_shared_weight_to_model_if_possible(const std::shared_ptr<ov::Model> model, | ||
| const std::shared_ptr<const ov::IPlugin>& plugin, | ||
| const ov::AnyMap& properties); | ||
|
|
||
| bool m_is_eagle = false; | ||
|
|
||
| std::vector<std::shared_ptr<AlignedBuffer>> m_shared_weight_sources; | ||
| }; | ||
|
|
||
| } // namespace npuw | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using the SharedWeightAssigner we can get already several page-aligned 2GB buffers where all constant are allocated sequentially, nothing will need to be done here in that case. ZeroTensor CAN BE imported from that aligned memory without copying and reallocating.
However, we must be able to return several initInputsAllocatedTensor from that function, which must not be a problem as ones are never used in caller contexts