|
| 1 | +// Copyright (C) 2025 Intel Corporation |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | +// |
| 4 | + |
| 5 | +#include "test_engine/models/find_model.hpp" |
| 6 | +#include "test_engine/comparators/nrmse.hpp" |
| 7 | +#include "test_engine/simple_llm_pipeline.hpp" |
| 8 | +#include "intel_npu/npuw_private_properties.hpp" |
| 9 | +#include "openvino/util/shared_object.hpp" |
| 10 | +#include "openvino/util/file_util.hpp" |
| 11 | + |
| 12 | +#include <filesystem> |
| 13 | +#include <algorithm> |
| 14 | + |
| 15 | +#include <gtest/gtest.h> |
| 16 | + |
| 17 | +using namespace testing; |
| 18 | +using namespace ov::npuw::tests; |
| 19 | +using namespace ov::intel_npu::npuw; |
| 20 | + |
| 21 | +namespace { |
| 22 | +const std::string minicpm_05_b_name = "MiniCPM4-0.5B_int4_sym_group128_dyn_stateful"; |
| 23 | + |
| 24 | +struct GroundTruth { |
| 25 | + std::vector<int64_t> prompt; |
| 26 | + std::vector<int64_t> answer; |
| 27 | +}; |
| 28 | + |
| 29 | +const GroundTruth What_is_OpenVINO_templated = { |
| 30 | + // Prompt: |
| 31 | + // <|im_start|>user |
| 32 | + // What is OpenVINO?<|im_end|> |
| 33 | + // <|im_start|>assistant |
| 34 | + {73441, 3060, 5, 5856, 1410, 6404, 59408, 2097, 59383, 74, 73440, 59320, 5, 73441, 16434, 5}, |
| 35 | + // Answer: OpenVINO |
| 36 | + { 9254, 59408, 2097, 59383} |
| 37 | +}; |
| 38 | + |
| 39 | +using LLMTestParams = std::tuple<std::string, ov::AnyMap, GroundTruth>; |
| 40 | +} // anonymous namespace |
| 41 | + |
| 42 | +class LLMSmokeAccuracyTestsNPUW : public ::testing::TestWithParam<LLMTestParams> { |
| 43 | +public: |
| 44 | + void SetUp() override { |
| 45 | + // NOTE: TEMPLATE plugin in OpenVINO works for ~20 minute to generate |
| 46 | + // first token from prefill model and crashes on launch of |
| 47 | + // 3rd subrequest in generate model. |
| 48 | + // There is no such issue with CPU plugin, so CPU plugin was choosen |
| 49 | + // for accuracy checks. |
| 50 | + // Test only makes sense if CPU plugin is enabled. |
| 51 | +#if !defined(OPENVINO_STATIC_LIBRARY) && defined(WITH_CPU_PLUGIN) && \ |
| 52 | + (defined(OPENVINO_ARCH_X86) || defined(OPENVINO_ARCH_X86_64)) |
| 53 | + const char* cpu_plugin_file_name = "openvino_intel_cpu_plugin"; |
| 54 | + // Register CPU plugin in OpenVINO: |
| 55 | + try { |
| 56 | + core.register_plugin(std::string(cpu_plugin_file_name) + OV_BUILD_POSTFIX, "CPU"); |
| 57 | + } catch (ov::Exception& ex) { |
| 58 | + if (std::string{ex.what()}.find("Device with \"CPU\" is already registered in the OpenVINO Runtime") |
| 59 | + == std::string::npos) { |
| 60 | + throw ex; |
| 61 | + } |
| 62 | + } |
| 63 | +#else |
| 64 | + GTEST_SKIP() << "CPU plugin is not enabled or platform requirements are not met, skipping the test!"; |
| 65 | +#endif // not OPENVINO_STATIC_LIBRARY && WITH_CPU_PLUGIN && |
| 66 | + // (defined(OPENVINO_ARCH_X86) || defined(OPENVINO_ARCH_X86_64)) |
| 67 | + |
| 68 | + auto param = GetParam(); |
| 69 | + std::string model_name; |
| 70 | + ov::AnyMap config; |
| 71 | + GroundTruth input_and_reference_ids; |
| 72 | + std::tie(model_name, config, input_and_reference_ids) = param; |
| 73 | + |
| 74 | + model_path = find_model(model_name); |
| 75 | + if (model_path == "") { |
| 76 | + GTEST_SKIP() << "Test model is not found, skipping the test!"; |
| 77 | + } |
| 78 | + |
| 79 | + input_ids = input_and_reference_ids.prompt; |
| 80 | + reference_ids = input_and_reference_ids.answer; |
| 81 | + |
| 82 | + config["NPUW_DEVICES"] = "CPU"; |
| 83 | + config["NPUW_LLM_MAX_PROMPT_LEN"] = 128; |
| 84 | + config["NPUW_LLM_MIN_RESPONSE_LEN"] = 4; |
| 85 | + simple_llm.initialize(model_path, core, config); |
| 86 | + } |
| 87 | + |
| 88 | +protected: |
| 89 | + ov::Core core; |
| 90 | + SimpleLLMPipeline simple_llm; |
| 91 | + std::string model_path; |
| 92 | + std::vector<int64_t> input_ids; |
| 93 | + std::vector<int64_t> actual_ids; |
| 94 | + std::vector<int64_t> reference_ids; |
| 95 | +}; |
| 96 | + |
| 97 | +TEST_P(LLMSmokeAccuracyTestsNPUW, ConfigIsAccurate) { |
| 98 | + actual_ids = simple_llm.generate(input_ids); |
| 99 | + for (std::size_t i = 0; i < actual_ids.size(); ++i) { |
| 100 | + ASSERT_EQ(actual_ids[i], reference_ids[i]); |
| 101 | + } |
| 102 | +} |
| 103 | + |
| 104 | +INSTANTIATE_TEST_SUITE_P(LLMSmokeAccuracyNPUW_FAST_COMPILE, LLMSmokeAccuracyTestsNPUW, |
| 105 | + ::testing::Combine(testing::Values(minicpm_05_b_name), |
| 106 | + testing::Values(ov::AnyMap{}), |
| 107 | + testing::Values(What_is_OpenVINO_templated))); |
0 commit comments