Skip to content

Commit 9788721

Browse files
[NPU] Update blob compatibility flexibility (#29387)
### Details: - currently, imported blobs with different OV version + hash are being discarded. This PR will make the version check more permissive and will accept blobs within the same OV release (major, minor, patch) - OV version is now represented as three `uint16_t` fields instead of a string - metadata major version is bumped - added a private NPU property, `DISABLE_VERSION_CHECK`, to bypass version checks. In dev builds, `OV_NPU_DISABLE_VERSION_CHECK` env var is still available for dev builds **IF** the property is not set. New metadata format: ![blob-layout_2025_1](https://github.com/user-attachments/assets/6bd7844a-45ae-468b-a9a3-c43fa4da65d1) ### Tickets: - *C-163952* --------- Signed-off-by: alexandruenache1111 <alexandru.enache@intel.com>
1 parent b59e74d commit 9788721

File tree

9 files changed

+129
-66
lines changed

9 files changed

+129
-66
lines changed

src/plugins/intel_npu/src/al/include/intel_npu/config/runtime.hpp

+20
Original file line numberDiff line numberDiff line change
@@ -309,4 +309,24 @@ struct RUN_INFERENCES_SEQUENTIALLY final : OptionBase<RUN_INFERENCES_SEQUENTIALL
309309
}
310310
};
311311

312+
struct DISABLE_VERSION_CHECK final : OptionBase<DISABLE_VERSION_CHECK, bool> {
313+
static std::string_view key() {
314+
return ov::intel_npu::disable_version_check.name();
315+
}
316+
317+
static bool defaultValue() {
318+
return false;
319+
}
320+
321+
#ifdef NPU_PLUGIN_DEVELOPER_BUILD
322+
static std::string_view envVar() {
323+
return "OV_NPU_DISABLE_VERSION_CHECK";
324+
}
325+
#endif
326+
327+
static OptionMode mode() {
328+
return OptionMode::RunTime;
329+
}
330+
};
331+
312332
} // namespace intel_npu

src/plugins/intel_npu/src/al/include/intel_npu/npu_private_properties.hpp

+7
Original file line numberDiff line numberDiff line change
@@ -329,5 +329,12 @@ static constexpr ov::Property<std::string> backend_compilation_params{"NPU_BACKE
329329
*/
330330
static constexpr ov::Property<bool> run_inferences_sequentially{"NPU_RUN_INFERENCES_SEQUENTIALLY"};
331331

332+
/**
333+
* @brief [Only for NPU Plugin]
334+
* Type: boolean, default is false.
335+
* This option allows to skip the blob version check
336+
*/
337+
static constexpr ov::Property<bool> disable_version_check{"NPU_DISABLE_VERSION_CHECK"};
338+
332339
} // namespace intel_npu
333340
} // namespace ov

src/plugins/intel_npu/src/al/src/config/runtime.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ void intel_npu::registerRunTimeOptions(OptionsDesc& desc) {
2929
desc.add<WEIGHTS_PATH>();
3030
desc.add<BYPASS_UMD_CACHING>();
3131
desc.add<RUN_INFERENCES_SEQUENTIALLY>();
32+
desc.add<DISABLE_VERSION_CHECK>();
3233
}
3334

3435
// Heuristically obtained number. Varies depending on the values of PLATFORM and PERFORMANCE_HINT

src/plugins/intel_npu/src/compiler_adapter/src/driver_compiler_adapter.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,11 @@ std::string DriverCompilerAdapter::serializeConfig(const Config& config,
598598
<< VALUE_DELIMITER;
599599
content = std::regex_replace(content, std::regex(umdcachestring.str()), "");
600600

601+
std::ostringstream skipversioncheck;
602+
skipversioncheck << ov::intel_npu::disable_version_check.name() << KEY_VALUE_SEPARATOR << VALUE_DELIMITER << "\\S+"
603+
<< VALUE_DELIMITER;
604+
content = std::regex_replace(content, std::regex(skipversioncheck.str()), "");
605+
601606
// FINAL step to convert prefixes of remaining params, to ensure backwards compatibility
602607
// From 5.0.0, driver compiler start to use NPU_ prefix, the old version uses VPU_ prefix
603608
if (compilerVersion.major < 5) {

src/plugins/intel_npu/src/plugin/include/metadata.hpp

+25-13
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
#include <memory>
99
#include <optional>
1010
#include <string>
11-
#include <vector>
11+
12+
#include "openvino/core/version.hpp"
1213

1314
namespace intel_npu {
1415

@@ -74,25 +75,29 @@ constexpr std::string_view MAGIC_BYTES = "OVNPU";
7475
/**
7576
* @brief List of supported version formats.
7677
*/
77-
constexpr uint32_t METADATA_VERSION_1_0{MetadataBase::make_version(1, 0)};
78+
constexpr uint32_t METADATA_VERSION_2_0{MetadataBase::make_version(2, 0)};
7879

7980
/**
8081
* @brief Current metadata version.
8182
*/
82-
constexpr uint32_t CURRENT_METADATA_VERSION{METADATA_VERSION_1_0};
83+
constexpr uint32_t CURRENT_METADATA_VERSION{METADATA_VERSION_2_0};
8384

8485
constexpr uint16_t CURRENT_METADATA_MAJOR_VERSION{MetadataBase::get_major(CURRENT_METADATA_VERSION)};
8586
constexpr uint16_t CURRENT_METADATA_MINOR_VERSION{MetadataBase::get_minor(CURRENT_METADATA_VERSION)};
8687

8788
struct OpenvinoVersion {
8889
private:
89-
std::string _version;
90-
uint32_t _size;
90+
uint16_t _major;
91+
uint16_t _minor;
92+
uint16_t _patch;
9193

9294
public:
93-
OpenvinoVersion();
95+
constexpr OpenvinoVersion(uint16_t major, uint16_t minor, uint16_t patch)
96+
: _major(major),
97+
_minor(minor),
98+
_patch(patch) {}
9499

95-
OpenvinoVersion(std::string_view version);
100+
OpenvinoVersion(const OpenvinoVersion& version);
96101

97102
/**
98103
* @brief Reads version data from a stream.
@@ -104,12 +109,19 @@ struct OpenvinoVersion {
104109
*/
105110
void write(std::ostream& stream);
106111

107-
/**
108-
* @brief Gets the version string.
109-
*/
110-
std::string get_version() const;
112+
uint16_t get_major() const;
113+
114+
uint16_t get_minor() const;
115+
116+
uint16_t get_patch() const;
117+
118+
bool operator!=(const OpenvinoVersion& version);
111119
};
112120

121+
constexpr OpenvinoVersion CURRENT_OPENVINO_VERSION(OPENVINO_VERSION_MAJOR,
122+
OPENVINO_VERSION_MINOR,
123+
OPENVINO_VERSION_PATCH);
124+
113125
/**
114126
* @brief Template for metadata class handling.
115127
*/
@@ -120,13 +132,13 @@ struct Metadata : public MetadataBase {};
120132
* @brief Template specialization for metadata version 1.0.
121133
*/
122134
template <>
123-
struct Metadata<METADATA_VERSION_1_0> : public MetadataBase {
135+
struct Metadata<METADATA_VERSION_2_0> : public MetadataBase {
124136
protected:
125137
OpenvinoVersion _ovVersion;
126138
uint64_t _blobDataSize;
127139

128140
public:
129-
Metadata(uint64_t blobSize, std::optional<std::string_view> ovVersion = std::nullopt);
141+
Metadata(uint64_t blobSize, std::optional<OpenvinoVersion> ovVersion = std::nullopt);
130142

131143
void read(std::istream& stream) override;
132144

src/plugins/intel_npu/src/plugin/src/compiled_model.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void CompiledModel::export_model(std::ostream& stream) const {
7676
_logger.debug("CompiledModel::export_model");
7777
size_t blobSizeBeforeVersioning = _graph->export_blob(stream);
7878

79-
auto meta = Metadata<CURRENT_METADATA_VERSION>(blobSizeBeforeVersioning, ov::get_openvino_version().buildNumber);
79+
auto meta = Metadata<CURRENT_METADATA_VERSION>(blobSizeBeforeVersioning, CURRENT_OPENVINO_VERSION);
8080
meta.write(stream);
8181
}
8282

src/plugins/intel_npu/src/plugin/src/metadata.cpp

+44-29
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,55 @@
66

77
#include <cstring>
88
#include <optional>
9-
#include <sstream>
109

11-
#include "intel_npu/config/config.hpp"
1210
#include "intel_npu/utils/logger/logger.hpp"
13-
#include "openvino/core/version.hpp"
1411
#include "openvino/runtime/shared_buffer.hpp"
1512

1613
namespace intel_npu {
1714

18-
OpenvinoVersion::OpenvinoVersion(std::string_view version)
19-
: _version(version),
20-
_size(static_cast<uint32_t>(version.size())) {}
15+
uint16_t OpenvinoVersion::get_major() const {
16+
return _major;
17+
}
18+
19+
uint16_t OpenvinoVersion::get_minor() const {
20+
return _minor;
21+
}
22+
23+
uint16_t OpenvinoVersion::get_patch() const {
24+
return _patch;
25+
}
26+
27+
bool OpenvinoVersion::operator!=(const OpenvinoVersion& version) {
28+
return this->_major != version._major || this->_minor != version._minor || this->_patch != version._patch;
29+
}
30+
31+
OpenvinoVersion::OpenvinoVersion(const OpenvinoVersion& version)
32+
: _major(version.get_major()),
33+
_minor(version.get_minor()),
34+
_patch(version.get_patch()) {}
2135

2236
void OpenvinoVersion::read(std::istream& stream) {
23-
stream.read(reinterpret_cast<char*>(&_size), sizeof(_size));
24-
_version.resize(_size);
25-
stream.read(_version.data(), _size);
37+
stream.read(reinterpret_cast<char*>(&_major), sizeof(_major));
38+
stream.read(reinterpret_cast<char*>(&_minor), sizeof(_minor));
39+
stream.read(reinterpret_cast<char*>(&_patch), sizeof(_patch));
2640
}
2741

2842
void OpenvinoVersion::write(std::ostream& stream) {
29-
stream.write(reinterpret_cast<const char*>(&_size), sizeof(_size));
30-
stream.write(_version.data(), _size);
43+
stream.write(reinterpret_cast<const char*>(&_major), sizeof(_major));
44+
stream.write(reinterpret_cast<const char*>(&_minor), sizeof(_minor));
45+
stream.write(reinterpret_cast<const char*>(&_patch), sizeof(_patch));
3146
}
3247

33-
Metadata<METADATA_VERSION_1_0>::Metadata(uint64_t blobSize, std::optional<std::string_view> ovVersion)
34-
: MetadataBase{METADATA_VERSION_1_0},
35-
_ovVersion{ovVersion.value_or(ov::get_openvino_version().buildNumber)},
48+
Metadata<METADATA_VERSION_2_0>::Metadata(uint64_t blobSize, std::optional<OpenvinoVersion> ovVersion)
49+
: MetadataBase{METADATA_VERSION_2_0},
50+
_ovVersion{ovVersion.value_or(CURRENT_OPENVINO_VERSION)},
3651
_blobDataSize{blobSize} {}
3752

38-
void Metadata<METADATA_VERSION_1_0>::read(std::istream& stream) {
53+
void Metadata<METADATA_VERSION_2_0>::read(std::istream& stream) {
3954
_ovVersion.read(stream);
4055
}
4156

42-
void Metadata<METADATA_VERSION_1_0>::write(std::ostream& stream) {
57+
void Metadata<METADATA_VERSION_2_0>::write(std::ostream& stream) {
4358
stream.write(reinterpret_cast<const char*>(&_version), sizeof(_version));
4459
_ovVersion.write(stream);
4560
stream.write(reinterpret_cast<const char*>(&_blobDataSize), sizeof(_blobDataSize));
@@ -53,25 +68,25 @@ std::unique_ptr<MetadataBase> create_metadata(uint32_t version, uint64_t blobSiz
5368
}
5469

5570
switch (version) {
56-
case METADATA_VERSION_1_0:
57-
return std::make_unique<Metadata<METADATA_VERSION_1_0>>(blobSize, std::nullopt);
71+
case METADATA_VERSION_2_0:
72+
return std::make_unique<Metadata<METADATA_VERSION_2_0>>(blobSize, std::nullopt);
5873

5974
default:
60-
OPENVINO_THROW("Invalid metadata version!");
75+
OPENVINO_THROW("Metadata version is not supported!");
6176
}
6277
}
6378

64-
std::string OpenvinoVersion::get_version() const {
65-
return _version;
66-
}
67-
68-
bool Metadata<METADATA_VERSION_1_0>::is_compatible() {
79+
bool Metadata<METADATA_VERSION_2_0>::is_compatible() {
6980
auto logger = Logger::global().clone("NPUBlobMetadata");
7081
// checking if we can import the blob
71-
if (_ovVersion.get_version() != ov::get_openvino_version().buildNumber) {
72-
logger.error("Imported blob OpenVINO version: %s, but the current OpenVINO version is: %s",
73-
_ovVersion.get_version().c_str(),
74-
ov::get_openvino_version().buildNumber);
82+
if (_ovVersion != CURRENT_OPENVINO_VERSION) {
83+
logger.error("Imported blob OpenVINO version: %d.%d.%d, but the current OpenVINO version is: %d.%d.%d",
84+
_ovVersion.get_major(),
85+
_ovVersion.get_minor(),
86+
_ovVersion.get_patch(),
87+
OPENVINO_VERSION_MAJOR,
88+
OPENVINO_VERSION_MINOR,
89+
OPENVINO_VERSION_PATCH);
7590
return false;
7691
}
7792
return true;
@@ -146,7 +161,7 @@ std::unique_ptr<MetadataBase> read_metadata_from(std::istream& stream) {
146161
return storedMeta;
147162
}
148163

149-
uint64_t Metadata<METADATA_VERSION_1_0>::get_blob_size() const {
164+
uint64_t Metadata<METADATA_VERSION_2_0>::get_blob_size() const {
150165
return _blobDataSize;
151166
}
152167

src/plugins/intel_npu/src/plugin/src/plugin.cpp

+11-13
Original file line numberDiff line numberDiff line change
@@ -581,9 +581,15 @@ Plugin::Plugin()
581581
[](const Config& config) {
582582
return config.get<RUN_INFERENCES_SEQUENTIALLY>();
583583
}}},
584-
{ov::intel_npu::batch_mode.name(), {false, ov::PropertyMutability::RW, [](const Config& config) {
585-
return config.getString<BATCH_MODE>();
586-
}}}};
584+
{ov::intel_npu::batch_mode.name(),
585+
{false,
586+
ov::PropertyMutability::RW,
587+
[](const Config& config) {
588+
return config.getString<BATCH_MODE>();
589+
}}},
590+
{ov::intel_npu::disable_version_check.name(), {false, ov::PropertyMutability::RW, [](const Config& config) {
591+
return config.getString<DISABLE_VERSION_CHECK>();
592+
}}}};
587593
}
588594

589595
void Plugin::reset_supported_properties() const {
@@ -865,24 +871,16 @@ std::shared_ptr<ov::ICompiledModel> Plugin::import_model(std::istream& stream, c
865871
CompilerAdapterFactory compilerAdapterFactory;
866872
auto compiler = compilerAdapterFactory.getCompiler(_backends->getIEngineBackend(), localConfig);
867873

868-
bool skipCompatibility = false;
869-
870-
#ifdef NPU_PLUGIN_DEVELOPER_BUILD
871-
if (auto envVar = std::getenv("OV_NPU_DISABLE_VERSION_CHECK")) {
872-
if (envVarStrToBool("OV_NPU_DISABLE_VERSION_CHECK", envVar)) {
873-
_logger.info("Blob compatibility check skipped.");
874-
skipCompatibility = true;
875-
}
876-
}
877-
#endif
878874
uint64_t graphSize;
875+
const bool skipCompatibility = localConfig.get<DISABLE_VERSION_CHECK>();
879876
if (!skipCompatibility) {
880877
auto storedMeta = read_metadata_from(stream);
881878
if (!storedMeta->is_compatible()) {
882879
OPENVINO_THROW("Incompatible blob version!");
883880
}
884881
graphSize = storedMeta->get_blob_size();
885882
} else {
883+
_logger.info("Blob compatibility check skipped.");
886884
graphSize = MetadataBase::getFileSize(stream);
887885
}
888886

0 commit comments

Comments
 (0)