diff --git a/.github/workflows/causal_lm_cpp.yml b/.github/workflows/causal_lm_cpp.yml
index 5fc4617f2c..2e0afaa882 100644
--- a/.github/workflows/causal_lm_cpp.yml
+++ b/.github/workflows/causal_lm_cpp.yml
@@ -16,10 +16,11 @@ concurrency:
cancel-in-progress: true
env:
- l_ov_link: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.0.0-17800-91ae987c516/l_openvino_toolkit_ubuntu20_2025.0.0.dev20250109_x86_64.tgz
- l_u22_ov_link: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.0.0-17800-91ae987c516/l_openvino_toolkit_ubuntu22_2025.0.0.dev20250109_x86_64.tgz
- m_ov_link: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.0.0-17800-91ae987c516/m_openvino_toolkit_macos_12_6_2025.0.0.dev20250109_x86_64.tgz
- w_ov_link: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.0.0-17800-91ae987c516/w_openvino_toolkit_windows_2025.0.0.dev20250109_x86_64.zip
+ l_ov_link: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.1.0-17911-83c047443de/l_openvino_toolkit_ubuntu20_2025.1.0.dev20250116_x86_64.tgz
+ l_u22_ov_link: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.1.0-17911-83c047443de/l_openvino_toolkit_ubuntu22_2025.1.0.dev20250116_x86_64.tgz
+ m_ov_link: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.1.0-17911-83c047443de/m_openvino_toolkit_macos_12_6_2025.1.0.dev20250116_x86_64.tgz
+ w_ov_link: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.1.0-17911-83c047443de/w_openvino_toolkit_windows_2025.1.0.dev20250116_x86_64.zip
+
jobs:
cpp-multinomial-greedy_causal_lm-ubuntu:
runs-on: ubuntu-20.04-8-cores
@@ -463,6 +464,7 @@ jobs:
env:
PYTHONPATH: "./build/:$PYTHONPATH"
LD_LIBRARY_PATH: "./build/openvino_genai/:$LD_LIBRARY_PATH"
+
cpp-prompt_lookup_decoding_lm-ubuntu:
runs-on: ubuntu-20.04-16-cores
defaults:
@@ -520,6 +522,7 @@ jobs:
env:
PYTHONPATH: "./build/:$PYTHONPATH"
LD_LIBRARY_PATH: "./build/openvino_genai/:$LD_LIBRARY_PATH"
+
cpp-Phi-1_5:
runs-on: ubuntu-20.04-16-cores
defaults:
@@ -697,7 +700,6 @@ jobs:
diff pred2.txt ref.txt
echo "Chat sample python" passed
-
visual_language_chat_sample-ubuntu-minicpm_v2_6:
runs-on: ubuntu-22.04-16-cores
steps:
@@ -836,6 +838,36 @@ jobs:
<<< $'Who drew this painting?\nWhen did the painter live?'
timeout-minutes: 4
+ visual_language_chat_sample-ubuntu-qwen2vl:
+ runs-on: ubuntu-22.04-16-cores
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ - uses: actions/setup-python@v4
+ with:
+ python-version: 3.11
+ - uses: ./.github/actions/install_openvino
+ with:
+ ov_link: ${{ env.l_u22_ov_link }}
+ - uses: ./.github/actions/build_app
+ with:
+ build_target: 'visual_language_chat py_openvino_genai'
+ - uses: ./.github/actions/install_python_deps
+ - name: Download and convert Qwen2VL model
+ run: |
+ source ./ov/setupvars.sh
+ optimum-cli export openvino --model Qwen/Qwen2-VL-2B-Instruct ./qwen2_vl_2b_ov/ --trust-remote-code
+ - name: Download images
+ run: |
+ wget https://llava-vl.github.io/static/images/monalisa.jpg
+ - name: Run visual_language_chat C++ sample - Qwen2VL
+ run: >
+ source ./ov/setupvars.sh
+ && ./build/samples/cpp/visual_language_chat/visual_language_chat ./qwen2_vl_2b_ov/ monalisa.jpg
+ <<< $'Who drew this painting?\nWhen did the painter live?'
+ timeout-minutes: 4
+
cpp-continuous-batching-ubuntu:
runs-on: ubuntu-20.04-8-cores
defaults:
diff --git a/.github/workflows/job_vlm_sample_llava.yml b/.github/workflows/job_vlm_sample_llava.yml
index a8a7a19a5b..1fb9cdee98 100644
--- a/.github/workflows/job_vlm_sample_llava.yml
+++ b/.github/workflows/job_vlm_sample_llava.yml
@@ -11,7 +11,7 @@ on:
type: string
env:
- l_u22_ov_link: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.0.0-17800-91ae987c516/l_openvino_toolkit_ubuntu22_2025.0.0.dev20250109_x86_64.tgz
+ l_u22_ov_link: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.1.0-17911-83c047443de/l_openvino_toolkit_ubuntu22_2025.1.0.dev20250116_x86_64.tgz
jobs:
visual_language_chat_sample-ubuntu-llava:
diff --git a/.github/workflows/lcm_dreamshaper_cpp.yml b/.github/workflows/lcm_dreamshaper_cpp.yml
index 6129aec624..55e4dc54ad 100644
--- a/.github/workflows/lcm_dreamshaper_cpp.yml
+++ b/.github/workflows/lcm_dreamshaper_cpp.yml
@@ -18,8 +18,8 @@ concurrency:
env:
PYTHON_VERSION: '3.9'
- LINUX_OV_ARCHIVE_URL: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.0.0-17800-91ae987c516/l_openvino_toolkit_ubuntu22_2025.0.0.dev20250109_x86_64.tgz
- WINDOWS_OV_ARCHIVE_URL: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.0.0-17800-91ae987c516/w_openvino_toolkit_windows_2025.0.0.dev20250109_x86_64.zip
+ LINUX_OV_ARCHIVE_URL: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.1.0-17911-83c047443de/l_openvino_toolkit_ubuntu22_2025.1.0.dev20250116_x86_64.tgz
+ WINDOWS_OV_ARCHIVE_URL: https://storage.openvinotoolkit.org/repositories/openvino/packages/nightly/2025.1.0-17911-83c047443de/w_openvino_toolkit_windows_2025.1.0.dev20250116_x86_64.zip
OV_INSTALL_DIR: ${{ github.workspace }}/ov
jobs:
@@ -93,7 +93,7 @@ jobs:
${{ env.build_dir }}/samples/cpp/image_generation/inpainting ./models/lcm_dreamshaper_v7 "cyberpunk cityscape like Tokyo New York with tall buildings at dusk golden hour cinematic lighting" ./image.png ./mask_image.png
lcm_dreamshaper_v7_cpp-windows:
- runs-on: windows-2019
+ runs-on: windows-2022
defaults:
run:
shell: pwsh
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3a67a24bab..bb19676da3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
@@ -30,7 +30,7 @@ if(UNIX AND NOT (APPLE OR ANDROID OR CYGWIN))
endif()
project(OpenVINOGenAI
- VERSION 2025.0.0.0
+ VERSION 2025.1.0.0
DESCRIPTION "OpenVINO GenAI"
HOMEPAGE_URL "https://github.com/openvinotoolkit/openvino.genai"
LANGUAGES CXX C)
diff --git a/SUPPORTED_MODELS.md b/SUPPORTED_MODELS.md
index 9487c715d9..f79234489d 100644
--- a/SUPPORTED_MODELS.md
+++ b/SUPPORTED_MODELS.md
@@ -362,6 +362,17 @@ In addition to image generation models, `InpaintingPipeline` supports specialize
+
+ Qwen2-VL |
+ Qwen2-VL |
+ Not supported |
+
+
+ |
+
diff --git a/cmake/features.cmake b/cmake/features.cmake
index 0434b21ee9..8b2e05472b 100644
--- a/cmake/features.cmake
+++ b/cmake/features.cmake
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
diff --git a/cmake/version.cmake b/cmake/version.cmake
index b9b51e8fe2..38c54a6b1c 100644
--- a/cmake/version.cmake
+++ b/cmake/version.cmake
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
diff --git a/pyproject.toml b/pyproject.toml
index 27318d42ed..722a012f34 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "openvino-genai"
-version = "2025.0.0.0"
+version = "2025.1.0.0"
description = "Library of the most popular Generative AI model pipelines, optimized execution methods, and samples"
requires-python = ">=3.9"
readme = { file = "src/README.md", content-type="text/markdown" }
@@ -30,7 +30,7 @@ classifiers = [
"Programming Language :: Python :: Implementation :: CPython"
]
dependencies = [
- "openvino_tokenizers~=2025.0.0.0.dev"
+ "openvino_tokenizers~=2025.1.0.0.dev"
]
[tool.py-build-cmake.module]
@@ -52,7 +52,7 @@ options = {"BUILD_TOKENIZERS" = "OFF"}
[build-system]
requires = [
"py-build-cmake==0.3.4",
- "openvino~=2025.0.0.0.dev",
+ "openvino~=2025.1.0.0.dev",
"pybind11-stubgen==2.5.1",
"cmake~=3.23.0"
]
diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt
index d32eb832a6..d84423b1e8 100644
--- a/samples/CMakeLists.txt
+++ b/samples/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
diff --git a/samples/cpp/image_generation/CMakeLists.txt b/samples/cpp/image_generation/CMakeLists.txt
index f3e4860ce0..16710d2697 100644
--- a/samples/cpp/image_generation/CMakeLists.txt
+++ b/samples/cpp/image_generation/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
find_package(OpenVINOGenAI REQUIRED
diff --git a/samples/cpp/image_generation/README.md b/samples/cpp/image_generation/README.md
index 3dcb64b97c..4d2b2ef9ff 100644
--- a/samples/cpp/image_generation/README.md
+++ b/samples/cpp/image_generation/README.md
@@ -28,7 +28,7 @@ Users can change the sample code and play with the following generation paramete
The `--upgrade-strategy eager` option is needed to ensure `optimum-intel` is upgraded to the latest version.
-It's not required to install [../../export-requirements.txt](../../export requirements.txt) for deployment if the model has already been exported.
+It's not required to install [../../export-requirements.txt](../../export-requirements.txt) for deployment if the model has already been exported.
```sh
pip install --upgrade-strategy eager -r ../../requirements.txt
diff --git a/samples/cpp/image_generation/heterogeneous_stable_diffusion.cpp b/samples/cpp/image_generation/heterogeneous_stable_diffusion.cpp
index 1bba41ffc5..2e37c88f8b 100644
--- a/samples/cpp/image_generation/heterogeneous_stable_diffusion.cpp
+++ b/samples/cpp/image_generation/heterogeneous_stable_diffusion.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/text2image_pipeline.hpp"
diff --git a/samples/cpp/image_generation/image2image.cpp b/samples/cpp/image_generation/image2image.cpp
index 2e1e5f57ba..284948f38e 100644
--- a/samples/cpp/image_generation/image2image.cpp
+++ b/samples/cpp/image_generation/image2image.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/image2image_pipeline.hpp"
diff --git a/samples/cpp/image_generation/imwrite.cpp b/samples/cpp/image_generation/imwrite.cpp
index 373da7dfe8..18fba1ff34 100644
--- a/samples/cpp/image_generation/imwrite.cpp
+++ b/samples/cpp/image_generation/imwrite.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/samples/cpp/image_generation/imwrite.hpp b/samples/cpp/image_generation/imwrite.hpp
index 9da1b4af2f..464cbacd34 100644
--- a/samples/cpp/image_generation/imwrite.hpp
+++ b/samples/cpp/image_generation/imwrite.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/samples/cpp/image_generation/inpainting.cpp b/samples/cpp/image_generation/inpainting.cpp
index a446035e0f..2e866ca345 100644
--- a/samples/cpp/image_generation/inpainting.cpp
+++ b/samples/cpp/image_generation/inpainting.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/inpainting_pipeline.hpp"
diff --git a/samples/cpp/image_generation/load_image.cpp b/samples/cpp/image_generation/load_image.cpp
index 7f14e54b3e..69b69d9f15 100644
--- a/samples/cpp/image_generation/load_image.cpp
+++ b/samples/cpp/image_generation/load_image.cpp
@@ -1,5 +1,5 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/samples/cpp/image_generation/load_image.hpp b/samples/cpp/image_generation/load_image.hpp
index f66dd2caf2..a04749e1d0 100644
--- a/samples/cpp/image_generation/load_image.hpp
+++ b/samples/cpp/image_generation/load_image.hpp
@@ -1,5 +1,5 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/samples/cpp/image_generation/lora_text2image.cpp b/samples/cpp/image_generation/lora_text2image.cpp
index af042a2c89..d96df2ceb0 100644
--- a/samples/cpp/image_generation/lora_text2image.cpp
+++ b/samples/cpp/image_generation/lora_text2image.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/text2image_pipeline.hpp"
diff --git a/samples/cpp/image_generation/text2image.cpp b/samples/cpp/image_generation/text2image.cpp
index 5668259f90..0ec0f924e2 100644
--- a/samples/cpp/image_generation/text2image.cpp
+++ b/samples/cpp/image_generation/text2image.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/text2image_pipeline.hpp"
diff --git a/samples/cpp/text_generation/CMakeLists.txt b/samples/cpp/text_generation/CMakeLists.txt
index f798b4f5fc..efad21a647 100644
--- a/samples/cpp/text_generation/CMakeLists.txt
+++ b/samples/cpp/text_generation/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
find_package(OpenVINOGenAI REQUIRED
diff --git a/samples/cpp/text_generation/beam_search_causal_lm.cpp b/samples/cpp/text_generation/beam_search_causal_lm.cpp
index fc18fa8e0c..9e1ee069ad 100644
--- a/samples/cpp/text_generation/beam_search_causal_lm.cpp
+++ b/samples/cpp/text_generation/beam_search_causal_lm.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/samples/cpp/text_generation/benchmark_genai.cpp b/samples/cpp/text_generation/benchmark_genai.cpp
index 76f2cbef2c..4a8c8d0723 100644
--- a/samples/cpp/text_generation/benchmark_genai.cpp
+++ b/samples/cpp/text_generation/benchmark_genai.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/llm_pipeline.hpp"
diff --git a/samples/cpp/text_generation/chat_sample.cpp b/samples/cpp/text_generation/chat_sample.cpp
index 41d63fc0f1..c0d172563c 100644
--- a/samples/cpp/text_generation/chat_sample.cpp
+++ b/samples/cpp/text_generation/chat_sample.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/llm_pipeline.hpp"
diff --git a/samples/cpp/text_generation/encrypted_model_causal_lm.cpp b/samples/cpp/text_generation/encrypted_model_causal_lm.cpp
index 3ea94d605f..7926de5552 100644
--- a/samples/cpp/text_generation/encrypted_model_causal_lm.cpp
+++ b/samples/cpp/text_generation/encrypted_model_causal_lm.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/llm_pipeline.hpp"
diff --git a/samples/cpp/text_generation/greedy_causal_lm.cpp b/samples/cpp/text_generation/greedy_causal_lm.cpp
index b5ca59095b..ca5e193da1 100644
--- a/samples/cpp/text_generation/greedy_causal_lm.cpp
+++ b/samples/cpp/text_generation/greedy_causal_lm.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/llm_pipeline.hpp"
diff --git a/samples/cpp/text_generation/lora_greedy_causal_lm.cpp b/samples/cpp/text_generation/lora_greedy_causal_lm.cpp
index b854b95fd3..0a74a00599 100644
--- a/samples/cpp/text_generation/lora_greedy_causal_lm.cpp
+++ b/samples/cpp/text_generation/lora_greedy_causal_lm.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/llm_pipeline.hpp"
diff --git a/samples/cpp/text_generation/multinomial_causal_lm.cpp b/samples/cpp/text_generation/multinomial_causal_lm.cpp
index bb74deffb1..96744e6136 100644
--- a/samples/cpp/text_generation/multinomial_causal_lm.cpp
+++ b/samples/cpp/text_generation/multinomial_causal_lm.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/llm_pipeline.hpp"
diff --git a/samples/cpp/text_generation/prompt_lookup_decoding_lm.cpp b/samples/cpp/text_generation/prompt_lookup_decoding_lm.cpp
index 8b48dbade0..bf4d81daa2 100644
--- a/samples/cpp/text_generation/prompt_lookup_decoding_lm.cpp
+++ b/samples/cpp/text_generation/prompt_lookup_decoding_lm.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/samples/cpp/text_generation/speculative_decoding_lm.cpp b/samples/cpp/text_generation/speculative_decoding_lm.cpp
index e10228863f..8a34bbf8a9 100644
--- a/samples/cpp/text_generation/speculative_decoding_lm.cpp
+++ b/samples/cpp/text_generation/speculative_decoding_lm.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/samples/cpp/visual_language_chat/CMakeLists.txt b/samples/cpp/visual_language_chat/CMakeLists.txt
index 9d3dea68a3..6f209ad0c8 100644
--- a/samples/cpp/visual_language_chat/CMakeLists.txt
+++ b/samples/cpp/visual_language_chat/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
find_package(OpenVINOGenAI REQUIRED
diff --git a/samples/cpp/visual_language_chat/README.md b/samples/cpp/visual_language_chat/README.md
index 73baf0088a..0017bd0b7c 100644
--- a/samples/cpp/visual_language_chat/README.md
+++ b/samples/cpp/visual_language_chat/README.md
@@ -12,7 +12,7 @@ There are two sample files:
The `--upgrade-strategy eager` option is needed to ensure `optimum-intel` is upgraded to the latest version.
-It's not required to install [../../export-requirements.txt](../../export requirements.txt) for deployment if the model has already been exported.
+It's not required to install [../../export-requirements.txt](../../export-requirements.txt) for deployment if the model has already been exported.
```sh
pip install --upgrade-strategy eager -r ../../requirements.txt
diff --git a/samples/cpp/visual_language_chat/benchmark_vlm.cpp b/samples/cpp/visual_language_chat/benchmark_vlm.cpp
index 858a626fd5..8467738307 100644
--- a/samples/cpp/visual_language_chat/benchmark_vlm.cpp
+++ b/samples/cpp/visual_language_chat/benchmark_vlm.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/samples/cpp/visual_language_chat/load_image.cpp b/samples/cpp/visual_language_chat/load_image.cpp
index 6dd246d647..d4f0d5de28 100644
--- a/samples/cpp/visual_language_chat/load_image.cpp
+++ b/samples/cpp/visual_language_chat/load_image.cpp
@@ -1,5 +1,5 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/samples/cpp/visual_language_chat/load_image.hpp b/samples/cpp/visual_language_chat/load_image.hpp
index d0dcc271cd..5a72f8cdaf 100644
--- a/samples/cpp/visual_language_chat/load_image.hpp
+++ b/samples/cpp/visual_language_chat/load_image.hpp
@@ -1,5 +1,5 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/samples/cpp/whisper_speech_recognition/CMakeLists.txt b/samples/cpp/whisper_speech_recognition/CMakeLists.txt
index 39f017adb1..93b9e22941 100644
--- a/samples/cpp/whisper_speech_recognition/CMakeLists.txt
+++ b/samples/cpp/whisper_speech_recognition/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
find_package(OpenVINOGenAI REQUIRED
diff --git a/samples/cpp/whisper_speech_recognition/README.md b/samples/cpp/whisper_speech_recognition/README.md
index 2ea3322dee..47650b566c 100644
--- a/samples/cpp/whisper_speech_recognition/README.md
+++ b/samples/cpp/whisper_speech_recognition/README.md
@@ -6,7 +6,7 @@ This example showcases inference of speech recognition Whisper Models. The appli
The `--upgrade-strategy eager` option is needed to ensure `optimum-intel` is upgraded to the latest version.
-It's not required to install [../../export-requirements.txt](../../export requirements.txt) for deployment if the model has already been exported.
+It's not required to install [../../export-requirements.txt](../../export-requirements.txt) for deployment if the model has already been exported.
```sh
pip install --upgrade-strategy eager -r ../../requirements.txt
diff --git a/samples/cpp/whisper_speech_recognition/audio_utils.cpp b/samples/cpp/whisper_speech_recognition/audio_utils.cpp
index a64db44f3f..b769ded671 100644
--- a/samples/cpp/whisper_speech_recognition/audio_utils.cpp
+++ b/samples/cpp/whisper_speech_recognition/audio_utils.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "audio_utils.hpp"
diff --git a/samples/cpp/whisper_speech_recognition/audio_utils.hpp b/samples/cpp/whisper_speech_recognition/audio_utils.hpp
index 6e4b141d83..b8b022db5a 100644
--- a/samples/cpp/whisper_speech_recognition/audio_utils.hpp
+++ b/samples/cpp/whisper_speech_recognition/audio_utils.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/samples/cpp/whisper_speech_recognition/whisper_speech_recognition.cpp b/samples/cpp/whisper_speech_recognition/whisper_speech_recognition.cpp
index 3df17a77f5..3b2b4ff466 100644
--- a/samples/cpp/whisper_speech_recognition/whisper_speech_recognition.cpp
+++ b/samples/cpp/whisper_speech_recognition/whisper_speech_recognition.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "audio_utils.hpp"
diff --git a/samples/deployment-requirements.txt b/samples/deployment-requirements.txt
index c6ad9eaaa8..312bd79799 100644
--- a/samples/deployment-requirements.txt
+++ b/samples/deployment-requirements.txt
@@ -1,5 +1,5 @@
--extra-index-url https://storage.openvinotoolkit.org/simple/wheels/pre-release
--extra-index-url https://storage.openvinotoolkit.org/simple/wheels/nightly
-openvino_genai~=2025.0.0.0.dev
+openvino_genai~=2025.1.0.0.dev
librosa==0.10.2.post1 # For Whisper
pillow==11.1.0 # Image processing for VLMs
diff --git a/samples/export-requirements.txt b/samples/export-requirements.txt
index a6aa3870f4..c35c2ca6de 100644
--- a/samples/export-requirements.txt
+++ b/samples/export-requirements.txt
@@ -1,12 +1,12 @@
--extra-index-url https://download.pytorch.org/whl/cpu
--extra-index-url https://storage.openvinotoolkit.org/simple/wheels/pre-release
--extra-index-url https://storage.openvinotoolkit.org/simple/wheels/nightly
-openvino-tokenizers~=2025.0.0.0.dev
+openvino-tokenizers~=2025.1.0.0.dev
optimum-intel @ git+https://github.com/huggingface/optimum-intel.git
numpy<2.0.0; sys_platform == 'darwin'
einops==0.8.0 # For Qwen
transformers_stream_generator==0.0.5 # For Qwen
-diffusers==0.32.1 # For image generation pipelines
+diffusers==0.32.2 # For image generation pipelines
timm==1.0.13 # For exporting InternVL2
torchvision # For visual language models
transformers>=4.43 # For Whisper
diff --git a/samples/python/text_generation/benchmark_genai.py b/samples/python/text_generation/benchmark_genai.py
index a5ed4acfc1..d279ab95fc 100755
--- a/samples/python/text_generation/benchmark_genai.py
+++ b/samples/python/text_generation/benchmark_genai.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import argparse
diff --git a/samples/python/text_generation/multinomial_causal_lm.py b/samples/python/text_generation/multinomial_causal_lm.py
index 5ec9d54601..c915b89a2f 100755
--- a/samples/python/text_generation/multinomial_causal_lm.py
+++ b/samples/python/text_generation/multinomial_causal_lm.py
@@ -31,6 +31,7 @@ def __init__(self, tokenizer):
self.tokens_cache = []
self.text_queue = queue.Queue()
self.print_len = 0
+ self.decoded_lengths = []
def __iter__(self):
"""
@@ -80,30 +81,35 @@ def put(self, token_id: int) -> bool:
Returns:
bool: True if generation should be stopped, False otherwise.
- """
+ """
self.tokens_cache.append(token_id)
text = self.tokenizer.decode(self.tokens_cache)
+ self.decoded_lengths.append(len(text))
word = ''
+ delay_n_tokens = 3
if len(text) > self.print_len and '\n' == text[-1]:
# Flush the cache after the new line symbol.
- word = text[self.print_len:]
+ word = text[self.print_len:]
self.tokens_cache = []
+ self.decoded_lengths = []
self.print_len = 0
- elif len(text) >= 3 and text[-1] == chr(65533):
+ elif len(text) > 0 and text[-1] == chr(65533):
# Don't print incomplete text.
- pass
- elif len(text) > self.print_len:
- # It is possible to have a shorter text after adding new token.
- # Print to output only if text length is increaesed.
- word = text[self.print_len:]
- self.print_len = len(text)
- self.put_word(word)
-
+ self.decoded_lengths[-1] = -1
+ elif len(self.tokens_cache) >= delay_n_tokens:
+ print_until = self.decoded_lengths[-delay_n_tokens]
+ if print_until != -1 and print_until > self.print_len:
+ # It is possible to have a shorter text after adding new token.
+ # Print to output only if text length is increased and text is complete (print_until != -1).
+ word = text[self.print_len:print_until]
+ self.print_len = print_until
+ self.put_word(word)
+
if self.get_stop_flag():
# When generation is stopped from streamer then end is not called, need to call it here manually.
self.end()
- return True # True means stop generation
+ return True # True means stop generation
else:
return False # False means continue generation
@@ -129,6 +135,7 @@ def __init__(self, tokenizer, tokens_len):
def put(self, token_id: int) -> bool:
if (len(self.tokens_cache) + 1) % self.tokens_len != 0:
self.tokens_cache.append(token_id)
+ self.decoded_lengths.append(-1)
return False
return super().put(token_id)
diff --git a/samples/python/visual_language_chat/benchmark_vlm.py b/samples/python/visual_language_chat/benchmark_vlm.py
index 4a8f50de73..4ca272fd14 100755
--- a/samples/python/visual_language_chat/benchmark_vlm.py
+++ b/samples/python/visual_language_chat/benchmark_vlm.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import argparse
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d9f3cc64db..2f615a1b6f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt
index e954037daf..43bca747ec 100644
--- a/src/cpp/CMakeLists.txt
+++ b/src/cpp/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
diff --git a/src/cpp/include/openvino/genai/cache_eviction.hpp b/src/cpp/include/openvino/genai/cache_eviction.hpp
index b8312361eb..8bab2fd744 100644
--- a/src/cpp/include/openvino/genai/cache_eviction.hpp
+++ b/src/cpp/include/openvino/genai/cache_eviction.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/continuous_batching_pipeline.hpp b/src/cpp/include/openvino/genai/continuous_batching_pipeline.hpp
index ed9fc3a30d..6c5552a7b5 100644
--- a/src/cpp/include/openvino/genai/continuous_batching_pipeline.hpp
+++ b/src/cpp/include/openvino/genai/continuous_batching_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/generation_config.hpp b/src/cpp/include/openvino/genai/generation_config.hpp
index 164ff29131..3a75fc02ea 100644
--- a/src/cpp/include/openvino/genai/generation_config.hpp
+++ b/src/cpp/include/openvino/genai/generation_config.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/generation_handle.hpp b/src/cpp/include/openvino/genai/generation_handle.hpp
index 953e573edd..6619e3e012 100644
--- a/src/cpp/include/openvino/genai/generation_handle.hpp
+++ b/src/cpp/include/openvino/genai/generation_handle.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/autoencoder_kl.hpp b/src/cpp/include/openvino/genai/image_generation/autoencoder_kl.hpp
index d48661d899..13da4a5317 100644
--- a/src/cpp/include/openvino/genai/image_generation/autoencoder_kl.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/autoencoder_kl.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/clip_text_model.hpp b/src/cpp/include/openvino/genai/image_generation/clip_text_model.hpp
index a3b9ebbd88..06196efe59 100644
--- a/src/cpp/include/openvino/genai/image_generation/clip_text_model.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/clip_text_model.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/clip_text_model_with_projection.hpp b/src/cpp/include/openvino/genai/image_generation/clip_text_model_with_projection.hpp
index 563fb8711d..cb74d8a214 100644
--- a/src/cpp/include/openvino/genai/image_generation/clip_text_model_with_projection.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/clip_text_model_with_projection.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/flux_transformer_2d_model.hpp b/src/cpp/include/openvino/genai/image_generation/flux_transformer_2d_model.hpp
index 95f846668b..ae9a6cb4ce 100644
--- a/src/cpp/include/openvino/genai/image_generation/flux_transformer_2d_model.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/flux_transformer_2d_model.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/generation_config.hpp b/src/cpp/include/openvino/genai/image_generation/generation_config.hpp
index bd7073520a..6d6b2ed35a 100644
--- a/src/cpp/include/openvino/genai/image_generation/generation_config.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/generation_config.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/image2image_pipeline.hpp b/src/cpp/include/openvino/genai/image_generation/image2image_pipeline.hpp
index c6c1f59c88..b086bd2aad 100644
--- a/src/cpp/include/openvino/genai/image_generation/image2image_pipeline.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/image2image_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/inpainting_pipeline.hpp b/src/cpp/include/openvino/genai/image_generation/inpainting_pipeline.hpp
index 03dd9468f7..1f8833d406 100644
--- a/src/cpp/include/openvino/genai/image_generation/inpainting_pipeline.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/inpainting_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/scheduler.hpp b/src/cpp/include/openvino/genai/image_generation/scheduler.hpp
index 25c5e07a2f..6e51f81917 100644
--- a/src/cpp/include/openvino/genai/image_generation/scheduler.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/scheduler.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/sd3_transformer_2d_model.hpp b/src/cpp/include/openvino/genai/image_generation/sd3_transformer_2d_model.hpp
index 7f96af49c2..281771fdfc 100644
--- a/src/cpp/include/openvino/genai/image_generation/sd3_transformer_2d_model.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/sd3_transformer_2d_model.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/t5_encoder_model.hpp b/src/cpp/include/openvino/genai/image_generation/t5_encoder_model.hpp
index 11797226eb..5e2e1716c5 100644
--- a/src/cpp/include/openvino/genai/image_generation/t5_encoder_model.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/t5_encoder_model.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/text2image_pipeline.hpp b/src/cpp/include/openvino/genai/image_generation/text2image_pipeline.hpp
index 3dc1fc0803..11787869cf 100644
--- a/src/cpp/include/openvino/genai/image_generation/text2image_pipeline.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/text2image_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/image_generation/unet2d_condition_model.hpp b/src/cpp/include/openvino/genai/image_generation/unet2d_condition_model.hpp
index 4acfd2ce9b..f0084d44b4 100644
--- a/src/cpp/include/openvino/genai/image_generation/unet2d_condition_model.hpp
+++ b/src/cpp/include/openvino/genai/image_generation/unet2d_condition_model.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/llm_pipeline.hpp b/src/cpp/include/openvino/genai/llm_pipeline.hpp
index e7a7c40f9b..31b1ac1675 100644
--- a/src/cpp/include/openvino/genai/llm_pipeline.hpp
+++ b/src/cpp/include/openvino/genai/llm_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/lora_adapter.hpp b/src/cpp/include/openvino/genai/lora_adapter.hpp
index b6b91bee20..4357b1be5b 100644
--- a/src/cpp/include/openvino/genai/lora_adapter.hpp
+++ b/src/cpp/include/openvino/genai/lora_adapter.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/perf_metrics.hpp b/src/cpp/include/openvino/genai/perf_metrics.hpp
index 659239be66..1ea0fb55f9 100644
--- a/src/cpp/include/openvino/genai/perf_metrics.hpp
+++ b/src/cpp/include/openvino/genai/perf_metrics.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/scheduler_config.hpp b/src/cpp/include/openvino/genai/scheduler_config.hpp
index 45d98c51bb..a551b866c6 100644
--- a/src/cpp/include/openvino/genai/scheduler_config.hpp
+++ b/src/cpp/include/openvino/genai/scheduler_config.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/streamer_base.hpp b/src/cpp/include/openvino/genai/streamer_base.hpp
index 724ec08f39..f286e896e5 100644
--- a/src/cpp/include/openvino/genai/streamer_base.hpp
+++ b/src/cpp/include/openvino/genai/streamer_base.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/tokenizer.hpp b/src/cpp/include/openvino/genai/tokenizer.hpp
index 548e4dc332..0a54d1da2a 100644
--- a/src/cpp/include/openvino/genai/tokenizer.hpp
+++ b/src/cpp/include/openvino/genai/tokenizer.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/visibility.hpp b/src/cpp/include/openvino/genai/visibility.hpp
index 4a1a60bb61..1daaf89ec6 100644
--- a/src/cpp/include/openvino/genai/visibility.hpp
+++ b/src/cpp/include/openvino/genai/visibility.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/visual_language/perf_metrics.hpp b/src/cpp/include/openvino/genai/visual_language/perf_metrics.hpp
index 18476a5e7f..86750a13f6 100644
--- a/src/cpp/include/openvino/genai/visual_language/perf_metrics.hpp
+++ b/src/cpp/include/openvino/genai/visual_language/perf_metrics.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/visual_language/pipeline.hpp b/src/cpp/include/openvino/genai/visual_language/pipeline.hpp
index 43f8a9b8b3..8c3d380b0f 100644
--- a/src/cpp/include/openvino/genai/visual_language/pipeline.hpp
+++ b/src/cpp/include/openvino/genai/visual_language/pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/whisper_generation_config.hpp b/src/cpp/include/openvino/genai/whisper_generation_config.hpp
index 44d611923d..12ca32ebb2 100644
--- a/src/cpp/include/openvino/genai/whisper_generation_config.hpp
+++ b/src/cpp/include/openvino/genai/whisper_generation_config.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/include/openvino/genai/whisper_pipeline.hpp b/src/cpp/include/openvino/genai/whisper_pipeline.hpp
index 6078298c60..8ba6a6a8e1 100644
--- a/src/cpp/include/openvino/genai/whisper_pipeline.hpp
+++ b/src/cpp/include/openvino/genai/whisper_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/attention_output.hpp b/src/cpp/src/attention_output.hpp
index b46ede11d2..602fcda1a0 100644
--- a/src/cpp/src/attention_output.hpp
+++ b/src/cpp/src/attention_output.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/block_manager.hpp b/src/cpp/src/block_manager.hpp
index 4ca263777b..0e1fe547d4 100644
--- a/src/cpp/src/block_manager.hpp
+++ b/src/cpp/src/block_manager.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/cache_eviction.cpp b/src/cpp/src/cache_eviction.cpp
index 94f3110cce..d6533daeb1 100644
--- a/src/cpp/src/cache_eviction.cpp
+++ b/src/cpp/src/cache_eviction.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "cache_eviction.hpp"
diff --git a/src/cpp/src/cache_eviction.hpp b/src/cpp/src/cache_eviction.hpp
index a32eb1ad0a..d2c8d0a553 100644
--- a/src/cpp/src/cache_eviction.hpp
+++ b/src/cpp/src/cache_eviction.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/cache_manager.hpp b/src/cpp/src/cache_manager.hpp
index 20d4c0c51c..13d75bac43 100644
--- a/src/cpp/src/cache_manager.hpp
+++ b/src/cpp/src/cache_manager.hpp
@@ -1,15 +1,49 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include
#include
-
#include "openvino/runtime/tensor.hpp"
-
#include "device_config.hpp"
+#ifndef _WIN32
+#include
+#include "openvino/core/shape.hpp"
+
+
+class TensorMmapAllocator {
+ size_t m_total_size;
+ void* m_data;
+
+public:
+ TensorMmapAllocator(size_t total_size) :
+ m_total_size(total_size) { }
+
+ void* allocate(size_t bytes, size_t) {
+ if (m_total_size == bytes) {
+ m_data = mmap(NULL, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ OPENVINO_ASSERT(m_data != MAP_FAILED);
+ return m_data;
+ }
+ throw std::runtime_error{"Unexpected number of bytes was requested to allocate."};
+ }
+
+ void deallocate(void*, size_t bytes, size_t) {
+ if (m_total_size != bytes) {
+ throw std::runtime_error{"Unexpected number of bytes was requested to deallocate."};
+ }
+ munmap(m_data, bytes);
+ }
+
+ bool is_equal(const TensorMmapAllocator& other) const noexcept {
+ return this == &other;
+ }
+};
+
+#endif
+
namespace ov::genai {
class CacheManager {
DeviceConfig m_device_config;
@@ -56,8 +90,17 @@ class CacheManager {
for (size_t decoder_layer_id = 0; decoder_layer_id < m_device_config.get_num_layers(); ++decoder_layer_id) {
ov::Shape value_cache_shape = set_first_dim_and_make_static(m_device_config.get_value_cache_shape(decoder_layer_id), num_kv_blocks);
ov::Shape key_cache_shape = set_first_dim_and_make_static(m_device_config.get_key_cache_shape(decoder_layer_id), num_kv_blocks);
+#ifdef _WIN32
ov::Tensor key_cache(m_device_config.get_cache_precision(), key_cache_shape);
ov::Tensor value_cache(m_device_config.get_cache_precision(), value_cache_shape);
+#else
+ auto key_size = ov::shape_size(key_cache_shape) * m_device_config.get_cache_precision().size();
+ auto value_size = ov::shape_size(value_cache_shape) * m_device_config.get_cache_precision().size();
+
+ ov::Tensor key_cache = ov::Tensor(m_device_config.get_cache_precision(), key_cache_shape, TensorMmapAllocator(key_size));
+ ov::Tensor value_cache = ov::Tensor(m_device_config.get_cache_precision(), value_cache_shape, TensorMmapAllocator(value_size));
+
+#endif
auto key_cache_roi_end = static_cast(key_cache.data());
auto value_cache_roi_end = static_cast(value_cache.data());
@@ -82,13 +125,14 @@ class CacheManager {
}
+#ifdef _WIN32
// Some optimizations like AVX2, AVX512, AMX require a minimal shape and
// perform multiplying by zero on the excess data. Uninitialized tensor data contain NAN's,
// so NAN * 0 returns non-zero invalid data.
// So we need to set zeros to all newly allocated tensors data.
std::memset(key_cache_roi_end, 0, key_cache.get_byte_size() - key_roi_size_byte);
std::memset(value_cache_roi_end, 0, value_cache.get_byte_size() - value_roi_size_byte);
-
+#endif
// set new cache tensors
if (m_key_cache.size() > decoder_layer_id) {
m_key_cache[decoder_layer_id] = key_cache;
diff --git a/src/cpp/src/cache_state_dumper.hpp b/src/cpp/src/cache_state_dumper.hpp
index ec6b63fdfb..e5292bf871 100644
--- a/src/cpp/src/cache_state_dumper.hpp
+++ b/src/cpp/src/cache_state_dumper.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -40,15 +40,15 @@ class CacheStateDumper {
* @param block_mgr A block manager owning the caches.
* @param sequence_groups Sequence groups currently utilizing the cache.
*/
- void dump_cache_state(const BlockManager &block_mgr, const std::vector &sequence_groups,
+ void dump_cache_state(const std::shared_ptr block_mgr, const std::vector &sequence_groups,
size_t dump_count) {
- for (size_t layer_idx = 0; layer_idx < block_mgr.m_num_layers; layer_idx++) {
+ for (size_t layer_idx = 0; layer_idx < block_mgr->m_num_layers; layer_idx++) {
auto per_layer_folder = get_per_layer_folder(layer_idx);
auto file_path = (per_layer_folder / (m_run_id + ".txt")).string();
std::ofstream out_stream(file_path, std::ios::out);
OPENVINO_ASSERT(out_stream.is_open());
- out_stream << block_mgr.m_allocator.m_total_num_blocks << std::endl;
+ out_stream << block_mgr->m_allocator.m_total_num_blocks << std::endl;
out_stream << sequence_groups.size() << std::endl;
for (const auto &seq_group_ptr: sequence_groups) {
out_stream << seq_group_ptr->get_request_id() << ' ';
@@ -57,7 +57,7 @@ class CacheStateDumper {
}
out_stream << std::endl;
}
- for (const auto &seq_id_and_blocks: block_mgr.m_block_table) {
+ for (const auto &seq_id_and_blocks: block_mgr->m_block_table) {
for (const auto &block: seq_id_and_blocks.second[layer_idx]) {
const size_t seq_id = seq_id_and_blocks.first;
out_stream << seq_id << " " << block->get_index() << " " << block->get_references_count()
@@ -70,7 +70,7 @@ class CacheStateDumper {
std::ofstream out_stream_cache_usage;
out_stream_cache_usage.open(cache_usage_file_path, std::ios::app);
- out_stream_cache_usage << dump_count << ' ' << block_mgr.get_used_percentage() << std::endl;
+ out_stream_cache_usage << dump_count << ' ' << block_mgr->get_used_percentage() << std::endl;
out_stream_cache_usage.flush();
dump_count++;
}
diff --git a/src/cpp/src/circular_buffer_queue.hpp b/src/cpp/src/circular_buffer_queue.hpp
index 859e4ec670..73e4644cb8 100644
--- a/src/cpp/src/circular_buffer_queue.hpp
+++ b/src/cpp/src/circular_buffer_queue.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/continuous_batching_adapter.hpp b/src/cpp/src/continuous_batching_adapter.hpp
index efcd2ec382..00928b342d 100644
--- a/src/cpp/src/continuous_batching_adapter.hpp
+++ b/src/cpp/src/continuous_batching_adapter.hpp
@@ -1,5 +1,5 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "llm_pipeline_base.hpp"
diff --git a/src/cpp/src/continuous_batching_impl.cpp b/src/cpp/src/continuous_batching_impl.cpp
index e778e55b93..788da2b015 100644
--- a/src/cpp/src/continuous_batching_impl.cpp
+++ b/src/cpp/src/continuous_batching_impl.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "text_callback_streamer.hpp"
@@ -33,6 +33,12 @@ ContinuousBatchingPipeline::ContinuousBatchingImpl::ContinuousBatchingImpl(
initialize_pipeline(model, scheduler_config, properties, device_config, core);
}
+ContinuousBatchingPipeline::ContinuousBatchingImpl::~ContinuousBatchingImpl() {
+ if (m_scheduler) {
+ m_scheduler->release();
+ }
+}
+
void ContinuousBatchingPipeline::ContinuousBatchingImpl::_pull_awaiting_requests() {
std::lock_guard lock{m_awaiting_requests_mutex};
m_requests.insert(m_requests.end(), m_awaiting_requests.begin(), m_awaiting_requests.end());
@@ -61,7 +67,7 @@ void ContinuousBatchingPipeline::ContinuousBatchingImpl::initialize_pipeline(
ov::InferRequest infer_request = compiled_model.create_infer_request();
// setup KV caches
- m_cache_manager = std::make_shared(device_config, infer_request, core);
+ std::shared_ptr cache_manager = std::make_shared(device_config, infer_request, core);
SchedulerConfig updated_config = scheduler_config;
// update KV blocks number in scheduler config
@@ -75,8 +81,7 @@ void ContinuousBatchingPipeline::ContinuousBatchingImpl::initialize_pipeline(
// as it may lead to performance slowdown
can_use_partial_preemption = false;
}
- m_scheduler = std::make_shared(device_config.get_block_size(), m_cache_manager, updated_config, device_config.get_num_layers(), can_use_partial_preemption);
-
+ m_scheduler = std::make_shared(device_config.get_block_size(), cache_manager, updated_config, device_config.get_num_layers(), can_use_partial_preemption);
// model runner
bool is_use_cache_eviction = m_scheduler->get_config().use_cache_eviction;
m_model_runner = std::make_shared(infer_request, m_scheduler->get_block_size(), device_config.get_num_layers(), is_use_cache_eviction);
@@ -158,11 +163,6 @@ void ContinuousBatchingPipeline::ContinuousBatchingImpl::step() {
SequenceGroup::CPtr sequence_group = m_requests[seq_group_id];
m_batch_size += sequence_group->num_running_seqs();
}
-
- static ManualTimer copy_blocks_timer("scheduling");
- copy_blocks_timer.start();
- m_cache_manager->copy_blocks(scheduler_output.m_block_copy_map);
- copy_blocks_timer.end();
}
// if no tokens were scheduled, we are out of memory => free all requests and return
diff --git a/src/cpp/src/continuous_batching_impl.hpp b/src/cpp/src/continuous_batching_impl.hpp
index 78e6638fbc..8980038f73 100644
--- a/src/cpp/src/continuous_batching_impl.hpp
+++ b/src/cpp/src/continuous_batching_impl.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -13,7 +13,6 @@ namespace ov::genai {
class ContinuousBatchingPipeline::ContinuousBatchingImpl : public ContinuousBatchingPipeline::IContinuousBatchingPipeline {
protected:
std::shared_ptr m_scheduler;
- std::shared_ptr m_cache_manager;
std::shared_ptr m_model_runner;
std::optional m_adapter_controller;
std::shared_ptr m_sampler;
@@ -89,6 +88,8 @@ class ContinuousBatchingPipeline::ContinuousBatchingImpl : public ContinuousBatc
const ov::AnyMap& properties,
const ov::genai::GenerationConfig& generation_config,
bool is_validation_mode_enabled = false);
+
+ virtual ~ContinuousBatchingImpl();
GenerationHandle add_request(uint64_t request_id,
const ov::Tensor& input_ids,
diff --git a/src/cpp/src/continuous_batching_pipeline.cpp b/src/cpp/src/continuous_batching_pipeline.cpp
index d380d1c6c4..dab9fdff22 100644
--- a/src/cpp/src/continuous_batching_pipeline.cpp
+++ b/src/cpp/src/continuous_batching_pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/debug_utils.hpp b/src/cpp/src/debug_utils.hpp
index 415f8c0480..4c301493ce 100644
--- a/src/cpp/src/debug_utils.hpp
+++ b/src/cpp/src/debug_utils.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/device_config.hpp b/src/cpp/src/device_config.hpp
index fee6c7abd1..cbf3fe70c5 100644
--- a/src/cpp/src/device_config.hpp
+++ b/src/cpp/src/device_config.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/generation_config.cpp b/src/cpp/src/generation_config.cpp
index 25402e22e7..67682be787 100644
--- a/src/cpp/src/generation_config.cpp
+++ b/src/cpp/src/generation_config.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/generation_handle.cpp b/src/cpp/src/generation_handle.cpp
index 0f10a85a86..5d92c560e9 100644
--- a/src/cpp/src/generation_handle.cpp
+++ b/src/cpp/src/generation_handle.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/generation_stream.hpp b/src/cpp/src/generation_stream.hpp
index 518699ba36..d76d0cf7f4 100644
--- a/src/cpp/src/generation_stream.hpp
+++ b/src/cpp/src/generation_stream.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/icontinuous_batching.cpp b/src/cpp/src/icontinuous_batching.cpp
index 8fbb9619ea..78f8fda8f7 100644
--- a/src/cpp/src/icontinuous_batching.cpp
+++ b/src/cpp/src/icontinuous_batching.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "icontinuous_batching.hpp"
diff --git a/src/cpp/src/icontinuous_batching.hpp b/src/cpp/src/icontinuous_batching.hpp
index 81fff3f40c..11c9b67e69 100644
--- a/src/cpp/src/icontinuous_batching.hpp
+++ b/src/cpp/src/icontinuous_batching.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/diffusion_pipeline.hpp b/src/cpp/src/image_generation/diffusion_pipeline.hpp
index 86d8ba9009..e7daf75fff 100644
--- a/src/cpp/src/image_generation/diffusion_pipeline.hpp
+++ b/src/cpp/src/image_generation/diffusion_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/flux_pipeline.hpp b/src/cpp/src/image_generation/flux_pipeline.hpp
index 458caf001b..fb6888b191 100644
--- a/src/cpp/src/image_generation/flux_pipeline.hpp
+++ b/src/cpp/src/image_generation/flux_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/generation_config.cpp b/src/cpp/src/image_generation/generation_config.cpp
index ab098fabe5..bdae31901e 100644
--- a/src/cpp/src/image_generation/generation_config.cpp
+++ b/src/cpp/src/image_generation/generation_config.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/generation_config.hpp"
diff --git a/src/cpp/src/image_generation/image2image_pipeline.cpp b/src/cpp/src/image_generation/image2image_pipeline.cpp
index 90c6e9fae4..8537e56ad5 100644
--- a/src/cpp/src/image_generation/image2image_pipeline.cpp
+++ b/src/cpp/src/image_generation/image2image_pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/image_generation/image_processor.cpp b/src/cpp/src/image_generation/image_processor.cpp
index 1e168da33b..3dabf888ab 100644
--- a/src/cpp/src/image_generation/image_processor.cpp
+++ b/src/cpp/src/image_generation/image_processor.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image_generation/image_processor.hpp"
diff --git a/src/cpp/src/image_generation/image_processor.hpp b/src/cpp/src/image_generation/image_processor.hpp
index 8c62742006..7b6fda89ad 100644
--- a/src/cpp/src/image_generation/image_processor.hpp
+++ b/src/cpp/src/image_generation/image_processor.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/inpainting_pipeline.cpp b/src/cpp/src/image_generation/inpainting_pipeline.cpp
index a9179f5fd0..25ac267b69 100644
--- a/src/cpp/src/image_generation/inpainting_pipeline.cpp
+++ b/src/cpp/src/image_generation/inpainting_pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/image_generation/models/autoencoder_kl.cpp b/src/cpp/src/image_generation/models/autoencoder_kl.cpp
index ab8b87a13e..bcec125375 100644
--- a/src/cpp/src/image_generation/models/autoencoder_kl.cpp
+++ b/src/cpp/src/image_generation/models/autoencoder_kl.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/autoencoder_kl.hpp"
@@ -22,6 +22,8 @@
namespace ov {
namespace genai {
+namespace {
+
class DiagonalGaussianDistribution {
public:
explicit DiagonalGaussianDistribution(ov::Tensor parameters)
@@ -64,6 +66,29 @@ class DiagonalGaussianDistribution {
ov::Tensor m_mean, m_std;
};
+// for BW compatibility with 2024.6.0
+ov::AnyMap handle_scale_factor(std::shared_ptr model, const std::string& device, ov::AnyMap properties) {
+ std::cout << ov::Any(properties).as() << std::endl;
+
+ auto it = properties.find("WA_INFERENCE_PRECISION_HINT");
+ ov::element::Type wa_inference_precision = it != properties.end() ? it->second.as() : ov::element::undefined;
+ if (it != properties.end()) {
+ properties.erase(it);
+ }
+
+ const std::vector activation_scale_factor_path = { "runtime_options", ov::hint::activations_scale_factor.name() };
+ const bool activation_scale_factor_defined = model->has_rt_info(activation_scale_factor_path);
+
+ // convert WA inference precision to actual inference precision if activation_scale_factor is not defined in IR
+ if (device.find("GPU") != std::string::npos && !activation_scale_factor_defined && wa_inference_precision != ov::element::undefined) {
+ properties[ov::hint::inference_precision.name()] = wa_inference_precision;
+ }
+
+ return properties;
+}
+
+} // namespace
+
size_t get_vae_scale_factor(const std::filesystem::path& vae_config_path) {
std::ifstream file(vae_config_path);
OPENVINO_ASSERT(file.is_open(), "Failed to open ", vae_config_path);
@@ -207,14 +232,14 @@ AutoencoderKL& AutoencoderKL::compile(const std::string& device, const ov::AnyMa
ov::Core core = utils::singleton_core();
if (m_encoder_model) {
- ov::CompiledModel encoder_compiled_model = core.compile_model(m_encoder_model, device, properties);
+ ov::CompiledModel encoder_compiled_model = core.compile_model(m_encoder_model, device, handle_scale_factor(m_encoder_model, device, properties));
ov::genai::utils::print_compiled_model_properties(encoder_compiled_model, "Auto encoder KL encoder model");
m_encoder_request = encoder_compiled_model.create_infer_request();
// release the original model
m_encoder_model.reset();
}
- ov::CompiledModel decoder_compiled_model = core.compile_model(m_decoder_model, device, properties);
+ ov::CompiledModel decoder_compiled_model = core.compile_model(m_decoder_model, device, handle_scale_factor(m_decoder_model, device, properties));
ov::genai::utils::print_compiled_model_properties(decoder_compiled_model, "Auto encoder KL decoder model");
m_decoder_request = decoder_compiled_model.create_infer_request();
// release the original model
diff --git a/src/cpp/src/image_generation/models/clip_text_model.cpp b/src/cpp/src/image_generation/models/clip_text_model.cpp
index c49bd5f000..603dad61a1 100644
--- a/src/cpp/src/image_generation/models/clip_text_model.cpp
+++ b/src/cpp/src/image_generation/models/clip_text_model.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/clip_text_model.hpp"
diff --git a/src/cpp/src/image_generation/models/clip_text_model_with_projection.cpp b/src/cpp/src/image_generation/models/clip_text_model_with_projection.cpp
index eb9289ab3e..eaf9d88db5 100644
--- a/src/cpp/src/image_generation/models/clip_text_model_with_projection.cpp
+++ b/src/cpp/src/image_generation/models/clip_text_model_with_projection.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/clip_text_model_with_projection.hpp"
diff --git a/src/cpp/src/image_generation/models/flux_transformer_2d_model.cpp b/src/cpp/src/image_generation/models/flux_transformer_2d_model.cpp
index 648eda8ff2..3bd5bc687d 100644
--- a/src/cpp/src/image_generation/models/flux_transformer_2d_model.cpp
+++ b/src/cpp/src/image_generation/models/flux_transformer_2d_model.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/flux_transformer_2d_model.hpp"
diff --git a/src/cpp/src/image_generation/models/sd3_transformer_2d_model.cpp b/src/cpp/src/image_generation/models/sd3_transformer_2d_model.cpp
index 0a7865b07a..ab04e22a1e 100644
--- a/src/cpp/src/image_generation/models/sd3_transformer_2d_model.cpp
+++ b/src/cpp/src/image_generation/models/sd3_transformer_2d_model.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/sd3_transformer_2d_model.hpp"
diff --git a/src/cpp/src/image_generation/models/t5_encoder_model.cpp b/src/cpp/src/image_generation/models/t5_encoder_model.cpp
index 32ae326eca..6b69b6d901 100644
--- a/src/cpp/src/image_generation/models/t5_encoder_model.cpp
+++ b/src/cpp/src/image_generation/models/t5_encoder_model.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/t5_encoder_model.hpp"
diff --git a/src/cpp/src/image_generation/models/unet2d_condition_model.cpp b/src/cpp/src/image_generation/models/unet2d_condition_model.cpp
index ef35709761..26da143d5b 100644
--- a/src/cpp/src/image_generation/models/unet2d_condition_model.cpp
+++ b/src/cpp/src/image_generation/models/unet2d_condition_model.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/image_generation/unet2d_condition_model.hpp"
diff --git a/src/cpp/src/image_generation/models/unet_inference.hpp b/src/cpp/src/image_generation/models/unet_inference.hpp
index ae928aac30..639338901b 100644
--- a/src/cpp/src/image_generation/models/unet_inference.hpp
+++ b/src/cpp/src/image_generation/models/unet_inference.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/models/unet_inference_dynamic.hpp b/src/cpp/src/image_generation/models/unet_inference_dynamic.hpp
index dd265e3eca..6bc86a5f06 100644
--- a/src/cpp/src/image_generation/models/unet_inference_dynamic.hpp
+++ b/src/cpp/src/image_generation/models/unet_inference_dynamic.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/models/unet_inference_static_bs1.hpp b/src/cpp/src/image_generation/models/unet_inference_static_bs1.hpp
index f63a8ea237..fd5d53e1d1 100644
--- a/src/cpp/src/image_generation/models/unet_inference_static_bs1.hpp
+++ b/src/cpp/src/image_generation/models/unet_inference_static_bs1.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/numpy_utils.hpp b/src/cpp/src/image_generation/numpy_utils.hpp
index 48c5192621..785271347d 100644
--- a/src/cpp/src/image_generation/numpy_utils.hpp
+++ b/src/cpp/src/image_generation/numpy_utils.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/schedulers/ddim.cpp b/src/cpp/src/image_generation/schedulers/ddim.cpp
index 768ba56837..2c0199051f 100644
--- a/src/cpp/src/image_generation/schedulers/ddim.cpp
+++ b/src/cpp/src/image_generation/schedulers/ddim.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/image_generation/schedulers/ddim.hpp b/src/cpp/src/image_generation/schedulers/ddim.hpp
index 7e042cf03e..9f3ecbf5ce 100644
--- a/src/cpp/src/image_generation/schedulers/ddim.hpp
+++ b/src/cpp/src/image_generation/schedulers/ddim.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/schedulers/euler_ancestral_discrete.cpp b/src/cpp/src/image_generation/schedulers/euler_ancestral_discrete.cpp
index a63a073cfc..383fece163 100644
--- a/src/cpp/src/image_generation/schedulers/euler_ancestral_discrete.cpp
+++ b/src/cpp/src/image_generation/schedulers/euler_ancestral_discrete.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/image_generation/schedulers/euler_ancestral_discrete.hpp b/src/cpp/src/image_generation/schedulers/euler_ancestral_discrete.hpp
index 9d82c9a0a9..71fa13f01c 100644
--- a/src/cpp/src/image_generation/schedulers/euler_ancestral_discrete.hpp
+++ b/src/cpp/src/image_generation/schedulers/euler_ancestral_discrete.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/schedulers/euler_discrete.cpp b/src/cpp/src/image_generation/schedulers/euler_discrete.cpp
index fe5c185437..fcfc854606 100644
--- a/src/cpp/src/image_generation/schedulers/euler_discrete.cpp
+++ b/src/cpp/src/image_generation/schedulers/euler_discrete.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image_generation/schedulers/euler_discrete.hpp"
diff --git a/src/cpp/src/image_generation/schedulers/euler_discrete.hpp b/src/cpp/src/image_generation/schedulers/euler_discrete.hpp
index 43620e7de4..0690258c9c 100644
--- a/src/cpp/src/image_generation/schedulers/euler_discrete.hpp
+++ b/src/cpp/src/image_generation/schedulers/euler_discrete.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/schedulers/flow_match_euler_discrete.cpp b/src/cpp/src/image_generation/schedulers/flow_match_euler_discrete.cpp
index 21d464d7f9..265a561869 100644
--- a/src/cpp/src/image_generation/schedulers/flow_match_euler_discrete.cpp
+++ b/src/cpp/src/image_generation/schedulers/flow_match_euler_discrete.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image_generation/schedulers/flow_match_euler_discrete.hpp"
diff --git a/src/cpp/src/image_generation/schedulers/flow_match_euler_discrete.hpp b/src/cpp/src/image_generation/schedulers/flow_match_euler_discrete.hpp
index 6410790b92..6399290ff3 100644
--- a/src/cpp/src/image_generation/schedulers/flow_match_euler_discrete.hpp
+++ b/src/cpp/src/image_generation/schedulers/flow_match_euler_discrete.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/schedulers/ischeduler.hpp b/src/cpp/src/image_generation/schedulers/ischeduler.hpp
index a6f61b5343..2dadd59b1b 100644
--- a/src/cpp/src/image_generation/schedulers/ischeduler.hpp
+++ b/src/cpp/src/image_generation/schedulers/ischeduler.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/schedulers/lcm.cpp b/src/cpp/src/image_generation/schedulers/lcm.cpp
index a447d23027..b232e17c11 100644
--- a/src/cpp/src/image_generation/schedulers/lcm.cpp
+++ b/src/cpp/src/image_generation/schedulers/lcm.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/image_generation/schedulers/lcm.hpp b/src/cpp/src/image_generation/schedulers/lcm.hpp
index b9e1a55270..2dc159002a 100644
--- a/src/cpp/src/image_generation/schedulers/lcm.hpp
+++ b/src/cpp/src/image_generation/schedulers/lcm.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/schedulers/lms_discrete.cpp b/src/cpp/src/image_generation/schedulers/lms_discrete.cpp
index d8c3c23745..be7d7a96df 100644
--- a/src/cpp/src/image_generation/schedulers/lms_discrete.cpp
+++ b/src/cpp/src/image_generation/schedulers/lms_discrete.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image_generation/schedulers/lms_discrete.hpp"
diff --git a/src/cpp/src/image_generation/schedulers/lms_discrete.hpp b/src/cpp/src/image_generation/schedulers/lms_discrete.hpp
index 53a3eb8c39..dd9e4125dc 100644
--- a/src/cpp/src/image_generation/schedulers/lms_discrete.hpp
+++ b/src/cpp/src/image_generation/schedulers/lms_discrete.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/schedulers/pndm.cpp b/src/cpp/src/image_generation/schedulers/pndm.cpp
index 4ddc099d0e..860b65be6f 100644
--- a/src/cpp/src/image_generation/schedulers/pndm.cpp
+++ b/src/cpp/src/image_generation/schedulers/pndm.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/image_generation/schedulers/pndm.hpp b/src/cpp/src/image_generation/schedulers/pndm.hpp
index 4e346f58b3..8089a46f09 100644
--- a/src/cpp/src/image_generation/schedulers/pndm.hpp
+++ b/src/cpp/src/image_generation/schedulers/pndm.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/schedulers/scheduler.cpp b/src/cpp/src/image_generation/schedulers/scheduler.cpp
index 868f6f05cf..2df1427f10 100644
--- a/src/cpp/src/image_generation/schedulers/scheduler.cpp
+++ b/src/cpp/src/image_generation/schedulers/scheduler.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/image_generation/schedulers/types.cpp b/src/cpp/src/image_generation/schedulers/types.cpp
index 5a9e5b6865..3d8721e25f 100644
--- a/src/cpp/src/image_generation/schedulers/types.cpp
+++ b/src/cpp/src/image_generation/schedulers/types.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "image_generation/schedulers/types.hpp"
diff --git a/src/cpp/src/image_generation/schedulers/types.hpp b/src/cpp/src/image_generation/schedulers/types.hpp
index bd5a8a7258..8ffe58670b 100644
--- a/src/cpp/src/image_generation/schedulers/types.hpp
+++ b/src/cpp/src/image_generation/schedulers/types.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/stable_diffusion_3_pipeline.hpp b/src/cpp/src/image_generation/stable_diffusion_3_pipeline.hpp
index ca7b1e9ca5..017a52a2ff 100644
--- a/src/cpp/src/image_generation/stable_diffusion_3_pipeline.hpp
+++ b/src/cpp/src/image_generation/stable_diffusion_3_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -137,25 +137,17 @@ class StableDiffusion3Pipeline : public DiffusionPipeline {
set_scheduler(Scheduler::from_config(root_dir / "scheduler/scheduler_config.json"));
- // Temporary fix for GPU
- ov::AnyMap updated_properties = properties;
- if (device.find("GPU") != std::string::npos &&
- updated_properties.find("INFERENCE_PRECISION_HINT") == updated_properties.end()) {
- updated_properties["INFERENCE_PRECISION_HINT"] = ov::element::f32;
- }
-
const std::string text_encoder = data["text_encoder"][1].get();
if (text_encoder == "CLIPTextModelWithProjection") {
m_clip_text_encoder_1 =
- std::make_shared(root_dir / "text_encoder", device, updated_properties);
+ std::make_shared(root_dir / "text_encoder", device, properties);
} else {
OPENVINO_THROW("Unsupported '", text_encoder, "' text encoder type");
}
const std::string text_encoder_2 = data["text_encoder_2"][1].get();
if (text_encoder_2 == "CLIPTextModelWithProjection") {
- m_clip_text_encoder_2 =
- std::make_shared(root_dir / "text_encoder_2", device, updated_properties);
+ m_clip_text_encoder_2 = std::make_shared(root_dir / "text_encoder_2", device, properties);
} else {
OPENVINO_THROW("Unsupported '", text_encoder_2, "' text encoder type");
}
@@ -164,7 +156,7 @@ class StableDiffusion3Pipeline : public DiffusionPipeline {
if (!text_encoder_3_json.is_null()) {
const std::string text_encoder_3 = text_encoder_3_json.get();
if (text_encoder_3 == "T5EncoderModel") {
- m_t5_text_encoder = std::make_shared(root_dir / "text_encoder_3", device, updated_properties);
+ m_t5_text_encoder = std::make_shared(root_dir / "text_encoder_3", device, properties);
} else {
OPENVINO_THROW("Unsupported '", text_encoder_3, "' text encoder type");
}
@@ -180,9 +172,9 @@ class StableDiffusion3Pipeline : public DiffusionPipeline {
const std::string vae = data["vae"][1].get();
if (vae == "AutoencoderKL") {
if (m_pipeline_type == PipelineType::TEXT_2_IMAGE)
- m_vae = std::make_shared(root_dir / "vae_decoder", device, updated_properties);
+ m_vae = std::make_shared(root_dir / "vae_decoder", device, properties);
else if (m_pipeline_type == PipelineType::IMAGE_2_IMAGE || m_pipeline_type == PipelineType::INPAINTING) {
- m_vae = std::make_shared(root_dir / "vae_encoder", root_dir / "vae_decoder", device, updated_properties);
+ m_vae = std::make_shared(root_dir / "vae_encoder", root_dir / "vae_decoder", device, properties);
} else {
OPENVINO_ASSERT("Unsupported pipeline type");
}
diff --git a/src/cpp/src/image_generation/stable_diffusion_pipeline.hpp b/src/cpp/src/image_generation/stable_diffusion_pipeline.hpp
index 3801c855fd..2c05bdb585 100644
--- a/src/cpp/src/image_generation/stable_diffusion_pipeline.hpp
+++ b/src/cpp/src/image_generation/stable_diffusion_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/image_generation/stable_diffusion_xl_pipeline.hpp b/src/cpp/src/image_generation/stable_diffusion_xl_pipeline.hpp
index c3ebcdf1f4..2553da93f9 100644
--- a/src/cpp/src/image_generation/stable_diffusion_xl_pipeline.hpp
+++ b/src/cpp/src/image_generation/stable_diffusion_xl_pipeline.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -77,7 +77,7 @@ class StableDiffusionXLPipeline : public StableDiffusionPipeline {
ov::AnyMap updated_properties = properties;
if (device.find("GPU") != std::string::npos &&
updated_properties.find("INFERENCE_PRECISION_HINT") == updated_properties.end()) {
- updated_properties["INFERENCE_PRECISION_HINT"] = ov::element::f32;
+ updated_properties["WA_INFERENCE_PRECISION_HINT"] = ov::element::f32;
}
const std::string vae = data["vae"][1].get();
diff --git a/src/cpp/src/image_generation/text2image_pipeline.cpp b/src/cpp/src/image_generation/text2image_pipeline.cpp
index 56b02a2e10..d4a5b0a77b 100644
--- a/src/cpp/src/image_generation/text2image_pipeline.cpp
+++ b/src/cpp/src/image_generation/text2image_pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/json_utils.hpp b/src/cpp/src/json_utils.hpp
index 4a4bb001df..c7af609242 100644
--- a/src/cpp/src/json_utils.hpp
+++ b/src/cpp/src/json_utils.hpp
@@ -1,5 +1,5 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/llm_pipeline.cpp b/src/cpp/src/llm_pipeline.cpp
index 11efed8b32..6ebef7bfba 100644
--- a/src/cpp/src/llm_pipeline.cpp
+++ b/src/cpp/src/llm_pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/llm_pipeline_stateful.cpp b/src/cpp/src/llm_pipeline_stateful.cpp
index 8451709092..2a53154c27 100644
--- a/src/cpp/src/llm_pipeline_stateful.cpp
+++ b/src/cpp/src/llm_pipeline_stateful.cpp
@@ -1,5 +1,5 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "llm_pipeline_stateful.hpp"
diff --git a/src/cpp/src/llm_pipeline_stateful.hpp b/src/cpp/src/llm_pipeline_stateful.hpp
index dbf8d89391..968c550a86 100644
--- a/src/cpp/src/llm_pipeline_stateful.hpp
+++ b/src/cpp/src/llm_pipeline_stateful.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
diff --git a/src/cpp/src/llm_pipeline_static.cpp b/src/cpp/src/llm_pipeline_static.cpp
index cffeedfc75..65f01ff193 100644
--- a/src/cpp/src/llm_pipeline_static.cpp
+++ b/src/cpp/src/llm_pipeline_static.cpp
@@ -34,6 +34,7 @@ namespace {
namespace opp = ov::pass::pattern;
class TransposeValueTensors : public ov::pass::MatcherPass {
public:
+ OPENVINO_MATCHER_PASS_RTTI("TransposeValueTensors");
struct Context {
std::vector> new_params;
std::vector> old_params;
@@ -95,7 +96,7 @@ class TransposeValueTensors : public ov::pass::MatcherPass {
class ScaledDotProductAttentionDecomposition : public ov::pass::MatcherPass {
public:
- OPENVINO_RTTI("ScaledDotProductAttentionDecomposition", "0");
+ OPENVINO_MATCHER_PASS_RTTI("ScaledDotProductAttentionDecomposition");
ScaledDotProductAttentionDecomposition() {
auto pattern_node = ov::pass::pattern::wrap_type();
@@ -769,9 +770,6 @@ void StatefulLLMPipeline::updateStatefulConfig(
rename_key(pipeline_config, "PREFILL_CONFIG", "NPUW_LLM_PREFILL_CONFIG");
rename_key(pipeline_config, "GENERATE_CONFIG", "NPUW_LLM_GENERATE_CONFIG");
rename_key(pipeline_config, "GENERATE_HINT", "NPUW_LLM_GENERATE_HINT");
-
- // Replace CACHE_DIR option if NPUW is enabled
- set_npuw_cache_dir(pipeline_config);
}
std::shared_ptr StatefulLLMPipeline::setupAndCompileModel(
@@ -1510,7 +1508,7 @@ LLMPipelineFactory::create(const std::filesystem::path& models_path,
const std::string& device,
const ov::AnyMap& config) {
auto properties = config;
- const auto pipeline_mode = str_to_pipeline(pop_or_default(properties, "STATIC_PIPELINE", std::string("STATELESS")));
+ const auto pipeline_mode = str_to_pipeline(pop_or_default(properties, "STATIC_PIPELINE", std::string("STATEFUL")));
if (pipeline_mode == StaticPipelineKind::STATEFUL) {
return std::make_unique(models_path, tokenizer, device, properties);
}
@@ -1531,7 +1529,7 @@ std::unique_ptr LLMPipelineFactory::create(const std::share
const ov::AnyMap& properties,
const ov::genai::GenerationConfig& generation_config) {
auto properties_copy = properties;
- const auto pipeline_mode = str_to_pipeline(pop_or_default(properties_copy, "STATIC_PIPELINE", std::string("STATELESS")));
+ const auto pipeline_mode = str_to_pipeline(pop_or_default(properties_copy, "STATIC_PIPELINE", std::string("STATEFUL")));
if (pipeline_mode == StaticPipelineKind::STATEFUL) {
return std::make_unique(model,
model_desc,
diff --git a/src/cpp/src/lm_encoding.cpp b/src/cpp/src/lm_encoding.cpp
index 424349f5aa..22fb0b1c02 100644
--- a/src/cpp/src/lm_encoding.cpp
+++ b/src/cpp/src/lm_encoding.cpp
@@ -29,6 +29,23 @@ void update_position_ids(ov::Tensor&& position_ids, const ov::Tensor&& attention
}
}
+void update_3d_position_ids(ov::Tensor&& position_ids, const ov::Tensor& attention_mask, const int64_t rope_delta) {
+ const size_t batch_size = attention_mask.get_shape().at(0);
+ const size_t sequence_length = attention_mask.get_shape().at(1);
+ const size_t thw_dim_size = 3;
+
+ position_ids.set_shape({thw_dim_size, batch_size, 1});
+ int64_t* position_ids_data = position_ids.data();
+
+ int64_t pos_id = static_cast(sequence_length) - 1 + rope_delta;
+
+ for (size_t batch = 0; batch < batch_size; batch++) {
+ for (size_t dim = 0; dim < thw_dim_size; ++dim) {
+ position_ids_data[dim * batch_size + batch] = pos_id;
+ }
+ }
+}
+
void update_attention_mask_with_beams(ov::Tensor&& attention_mask, std::vector next_beams) {
ov::Tensor original_mask{ov::element::i64, attention_mask.get_shape()};
ov::Shape original_shape = original_mask.get_shape();
@@ -58,7 +75,8 @@ std::pair> get_lm_encoded_results(
Sampler& sampler,
std::vector sequence_groups,
std::optional position_ids,
- std::optional m_embedding
+ std::optional m_embedding,
+ std::optional rope_delta
) {
std::vector generations;
for (SequenceGroup::Ptr sequence_group : sequence_groups) {
@@ -196,7 +214,11 @@ std::pair> get_lm_encoded_results(
update_attention_mask_with_beams(m_llm.get_tensor("attention_mask"), next_beams);
if (position_ids.has_value()) {
- update_position_ids(m_llm.get_tensor("position_ids"), m_llm.get_tensor("attention_mask"));
+ if (position_ids->get_shape().size() == 3 && rope_delta.has_value()) {
+ update_3d_position_ids(m_llm.get_tensor("position_ids"), m_llm.get_tensor("attention_mask"), rope_delta.value());
+ } else {
+ update_position_ids(m_llm.get_tensor("position_ids"), m_llm.get_tensor("attention_mask"));
+ }
}
m_llm.set_tensor("beam_idx", ov::Tensor{ov::element::i32, {total_num_tokens}, next_beams.data()});
diff --git a/src/cpp/src/lm_encoding.hpp b/src/cpp/src/lm_encoding.hpp
index c31cffb9bc..56f6db5227 100644
--- a/src/cpp/src/lm_encoding.hpp
+++ b/src/cpp/src/lm_encoding.hpp
@@ -10,7 +10,7 @@ namespace genai {
std::pair> get_lm_encoded_results(ov::InferRequest& m_llm, const ov::Tensor& input_ids, const ov::Tensor& attention_mask,
const std::shared_ptr& streamer_ptr, Sampler& sampler, std::vector sequence_groups,
- std::optional position_ids, std::optional m_embedding);
+ std::optional position_ids, std::optional m_embedding, std::optional rope_delta = std::nullopt);
}
}
diff --git a/src/cpp/src/logit_processor.hpp b/src/cpp/src/logit_processor.hpp
index a81a33017d..a9446591cf 100644
--- a/src/cpp/src/logit_processor.hpp
+++ b/src/cpp/src/logit_processor.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/lora_adapter.cpp b/src/cpp/src/lora_adapter.cpp
index e060e55160..2fd487f37f 100644
--- a/src/cpp/src/lora_adapter.cpp
+++ b/src/cpp/src/lora_adapter.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
@@ -473,7 +473,7 @@ struct LoRAWeightStateGetter {
class LoRATransformBase : public ov::pass::MatcherPass {
public:
- OPENVINO_RTTI("LoRATransformBase");
+ OPENVINO_MATCHER_PASS_RTTI("LoRATransformBase");
LoRATransformBase(const LoRAWeightByNodeGetter& lora_weight_getter) {
register_matcher(
@@ -693,7 +693,7 @@ class LoRAFuseTransform : public LoRATransformBase {
public:
- OPENVINO_RTTI("LoRAFuseTransform");
+ OPENVINO_RTTI("LoRAFuseTransform", "genai", LoRATransformBase);
LoRAFuseTransform(const LoRAWeightByNodeGetter& lora_weight_getter, const std::string& device_for_fusion = "CPU") :
LoRATransformBase(lora_weight_getter),
@@ -763,7 +763,7 @@ class LoRAFuseTransform : public LoRATransformBase {
class LoRASeparateTransform : public LoRATransformBase {
public:
- OPENVINO_RTTI("LoRASeparateTransform");
+ OPENVINO_RTTI("LoRASeparateTransform", "genai", LoRATransformBase);
LoRASeparateTransform(const LoRAWeightByNodeGetter& lora_getter) : LoRATransformBase(lora_getter) {}
diff --git a/src/cpp/src/lora_names_mapping.cpp b/src/cpp/src/lora_names_mapping.cpp
index 0be3e740b4..03bf2ed93c 100644
--- a/src/cpp/src/lora_names_mapping.cpp
+++ b/src/cpp/src/lora_names_mapping.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
// Content of this file is a C++ port of the name mapping for LoRA tensors from HuggingFace diffusers/loaders/lora_conversion_utils.py
diff --git a/src/cpp/src/make_tokenizer_stateful.cpp b/src/cpp/src/make_tokenizer_stateful.cpp
index 4685b0e715..547ecdac92 100644
--- a/src/cpp/src/make_tokenizer_stateful.cpp
+++ b/src/cpp/src/make_tokenizer_stateful.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "make_tokenizer_stateful.hpp"
diff --git a/src/cpp/src/make_tokenizer_stateful.hpp b/src/cpp/src/make_tokenizer_stateful.hpp
index 307c6199c8..9ad06ae07a 100644
--- a/src/cpp/src/make_tokenizer_stateful.hpp
+++ b/src/cpp/src/make_tokenizer_stateful.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/op/constant.hpp"
@@ -34,7 +34,7 @@ namespace genai {
**/
class MakeCombineSegmentsSatateful : public ov::pass::ModelPass {
public:
- OPENVINO_RTTI("MakeCombineSegmentsSatateful", "0");
+ OPENVINO_MODEL_PASS_RTTI("MakeCombineSegmentsSatateful");
bool run_on_model(const std::shared_ptr& model) override;
};
@@ -70,7 +70,7 @@ class MakeCombineSegmentsSatateful : public ov::pass::ModelPass {
**/
class MakeVocabDecoderSatateful : public ov::pass::ModelPass {
public:
- OPENVINO_RTTI("MakeVocabDecoderSatateful", "0");
+ OPENVINO_MODEL_PASS_RTTI("MakeVocabDecoderSatateful");
bool run_on_model(const std::shared_ptr& model) override;
};
diff --git a/src/cpp/src/model_runner.hpp b/src/cpp/src/model_runner.hpp
index 27eee9e27d..d12e69052b 100644
--- a/src/cpp/src/model_runner.hpp
+++ b/src/cpp/src/model_runner.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/perf_metrics.cpp b/src/cpp/src/perf_metrics.cpp
index f4ec0eb49a..a84b83dd2f 100644
--- a/src/cpp/src/perf_metrics.cpp
+++ b/src/cpp/src/perf_metrics.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/perf_metrics.hpp"
diff --git a/src/cpp/src/prompt_lookup/continuous_batching_for_prompt_lookup.cpp b/src/cpp/src/prompt_lookup/continuous_batching_for_prompt_lookup.cpp
index d6e2746244..d01c863549 100644
--- a/src/cpp/src/prompt_lookup/continuous_batching_for_prompt_lookup.cpp
+++ b/src/cpp/src/prompt_lookup/continuous_batching_for_prompt_lookup.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "continuous_batching_for_prompt_lookup.hpp"
diff --git a/src/cpp/src/prompt_lookup/continuous_batching_for_prompt_lookup.hpp b/src/cpp/src/prompt_lookup/continuous_batching_for_prompt_lookup.hpp
index e439fd03e1..fc4942701e 100644
--- a/src/cpp/src/prompt_lookup/continuous_batching_for_prompt_lookup.hpp
+++ b/src/cpp/src/prompt_lookup/continuous_batching_for_prompt_lookup.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/prompt_lookup/prompt_lookup_impl.cpp b/src/cpp/src/prompt_lookup/prompt_lookup_impl.cpp
index 68aada91dd..41c3e6370f 100644
--- a/src/cpp/src/prompt_lookup/prompt_lookup_impl.cpp
+++ b/src/cpp/src/prompt_lookup/prompt_lookup_impl.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "prompt_lookup_impl.hpp"
diff --git a/src/cpp/src/prompt_lookup/prompt_lookup_impl.hpp b/src/cpp/src/prompt_lookup/prompt_lookup_impl.hpp
index e19042f44e..1499bcc76e 100644
--- a/src/cpp/src/prompt_lookup/prompt_lookup_impl.hpp
+++ b/src/cpp/src/prompt_lookup/prompt_lookup_impl.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/scheduler.hpp b/src/cpp/src/scheduler.hpp
index 0057b19329..86f705f759 100644
--- a/src/cpp/src/scheduler.hpp
+++ b/src/cpp/src/scheduler.hpp
@@ -1,5 +1,5 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -13,13 +13,14 @@
#include "block_manager.hpp"
#include "sequence_group.hpp"
#include "cache_manager.hpp"
+#include "timer.hpp"
namespace ov::genai {
class Scheduler {
bool m_can_use_partial_preemption;
SchedulerConfig m_config;
- BlockManager m_block_manager;
+ std::shared_ptr m_block_manager;
friend class CacheStateDumper;
bool m_dynamic_memory_allocation = false;
@@ -33,8 +34,6 @@ class Scheduler {
struct Output {
// IDs of scheduled groups
std::vector m_scheduled_sequence_groups_ids;
- // map of src -> dst blocks copies, which need to be performed by CacheManager
- std::map> m_block_copy_map;
// block tables for scheduled sequences per each attention layer in the model
std::map> m_block_tables;
// total number of scheduled tokens
@@ -48,26 +47,32 @@ class Scheduler {
explicit Scheduler(size_t block_size, std::shared_ptr cache_manager, const SchedulerConfig & config = {}, size_t num_layers = 1, bool can_use_partial_preemption = true) :
m_cache_manager(cache_manager),
m_can_use_partial_preemption(can_use_partial_preemption),
- m_config(config),
- m_block_manager(m_config.num_kv_blocks, m_config.enable_prefix_caching, block_size, num_layers) {
-
+ m_config(config) {
+ m_block_manager = std::make_shared(m_config.num_kv_blocks, m_config.enable_prefix_caching, block_size, num_layers);
OPENVINO_ASSERT(num_layers != 0, "num_layers must be non-zero");
}
+ void release() {
+ m_cache_manager.reset();
+ m_block_manager.reset();
+ }
+
Output schedule(std::vector& sequence_groups) {
Output scheduler_output;
+ // map of src -> dst blocks copies, which need to be performed by CacheManager
+ std::map> block_copy_map;
// free some blocks taken by non-confirmed condidates in SD / prompt look-up
clean_empty_blocks(sequence_groups);
- if (m_block_manager.get_total_number_of_kv_blocks() == 0) {
+ if (m_block_manager->get_total_number_of_kv_blocks() == 0) {
_initialize_cache(sequence_groups);
}
if (m_config.dynamic_split_fuse) {
// deepspeed-mii case
// generation phase is always scheduled first
- _schedule_generate_phase_dynamic_split_fuse(sequence_groups, scheduler_output);
+ _schedule_generate_phase_dynamic_split_fuse(sequence_groups, scheduler_output, block_copy_map);
// some tokens from generation prompt are also scheduled
_schedule_prompt_phase_dynamic_split_fuse(sequence_groups, scheduler_output);
} else {
@@ -78,13 +83,19 @@ class Scheduler {
if (!scheduler_output.is_prompt) {
// prompt sequences are not scheduler => scheduler generation phase by dynamic_split_fuse implementation
- _schedule_generate_phase_dynamic_split_fuse(sequence_groups, scheduler_output);
+ _schedule_generate_phase_dynamic_split_fuse(sequence_groups, scheduler_output, block_copy_map);
}
}
- m_cache_manager->allocate_cache_if_needed(m_block_manager.get_total_number_of_kv_blocks());
+ m_cache_manager->allocate_cache_if_needed(m_block_manager->get_total_number_of_kv_blocks());
_clear_waiting_sequences(sequence_groups);
- scheduler_output.m_cache_usage = m_block_manager.get_used_percentage();
+ scheduler_output.m_cache_usage = m_block_manager->get_used_percentage();
+
+ static ManualTimer copy_blocks_timer("copy block");
+ copy_blocks_timer.start();
+ m_cache_manager->copy_blocks(block_copy_map);
+ copy_blocks_timer.end();
+
return scheduler_output;
}
@@ -94,31 +105,31 @@ class Scheduler {
*/
void clean_empty_blocks(std::vector& seq_groups) {
for (const auto& seq_group : seq_groups)
- m_block_manager.free_empty_physical_blocks(seq_group);
+ m_block_manager->free_empty_physical_blocks(seq_group);
}
const std::vector& get_block_tables(const Sequence& seq) const {
- return m_block_manager.get_block_tables(seq.get_id());
+ return m_block_manager->get_block_tables(seq.get_id());
}
const size_t get_block_size() const {
- return m_block_manager.get_block_size();
+ return m_block_manager->get_block_size();
}
const bool has_block_table(uint64_t seq_id) {
- return m_block_manager.has_block_table(seq_id);
+ return m_block_manager->has_block_table(seq_id);
}
void free_sequence(uint64_t seq_id) {
- m_block_manager.free_sequence(seq_id);
+ m_block_manager->free_sequence(seq_id);
}
void fork_sequence(uint64_t parent_id, uint64_t child_id) {
- m_block_manager.fork_sequence(parent_id, child_id);
+ m_block_manager->fork_sequence(parent_id, child_id);
}
void restore_cached_blocks(const SequenceGroup::Ptr& sequence_group) {
- m_block_manager.restore_cached_blocks(sequence_group);
+ m_block_manager->restore_cached_blocks(sequence_group);
}
const SchedulerConfig& get_config() const {
@@ -126,7 +137,7 @@ class Scheduler {
}
void free_blocks_from_sequence(size_t seq_id, const std::vector>& per_layer_logical_block_indices_to_free) {
- m_block_manager.free_blocks_from_sequence(seq_id, per_layer_logical_block_indices_to_free);
+ m_block_manager->free_blocks_from_sequence(seq_id, per_layer_logical_block_indices_to_free);
}
private:
@@ -143,31 +154,31 @@ class Scheduler {
bool _preempt_by_recompute(SequenceGroup::Ptr sequence_group, size_t blocks_needed) {
size_t processed_tokens = sequence_group->get_num_processed_tokens();
- size_t prev_blocks_count = m_block_manager.num_free_blocks();
+ size_t prev_blocks_count = m_block_manager->num_free_blocks();
size_t preempted_tokens = 0;
- size_t num_blocks_occupied_by_sequence = m_block_manager.get_number_of_blocks_occupied_by_sequence(sequence_group);
+ size_t num_blocks_occupied_by_sequence = m_block_manager->get_number_of_blocks_occupied_by_sequence(sequence_group);
bool was_evicted_from = (sequence_group->get_num_evicted_tokens() != 0);
if (num_blocks_occupied_by_sequence <= blocks_needed || !m_can_use_partial_preemption || was_evicted_from) {
auto sequences = sequence_group->get_not_finished_sequences();
for (size_t s = 0; s < sequences.size(); ++s) {
auto seq_id = sequences[s]->get_id();
- m_block_manager.free_sequence(seq_id);
+ m_block_manager->free_sequence(seq_id);
}
sequence_group->preempt_tokens(processed_tokens);
if (was_evicted_from) {
sequence_group->reset_eviction_token_count();
}
sequence_group->set_waiting();
- return m_block_manager.num_free_blocks() > prev_blocks_count;
+ return m_block_manager->num_free_blocks() > prev_blocks_count;
}
size_t logical_blocks_released;
if (sequence_group->get_sampling_parameters().is_beam_search()) {
- logical_blocks_released = m_block_manager.free_partially_beam_search_group(sequence_group, blocks_needed);
+ logical_blocks_released = m_block_manager->free_partially_beam_search_group(sequence_group, blocks_needed);
}
else {
- logical_blocks_released = m_block_manager.free_group_partially(sequence_group, blocks_needed);
+ logical_blocks_released = m_block_manager->free_group_partially(sequence_group, blocks_needed);
}
size_t block_size = get_block_size();
@@ -184,14 +195,14 @@ class Scheduler {
preempted_tokens = processed_tokens;
for (auto sequence: sequence_group->get_not_finished_sequences()) {
auto seq_id = sequence->get_id();
- if (m_block_manager.has_block_table(seq_id)) {
- m_block_manager.free_sequence(seq_id);
+ if (m_block_manager->has_block_table(seq_id)) {
+ m_block_manager->free_sequence(seq_id);
}
}
}
sequence_group->preempt_tokens(preempted_tokens);
sequence_group->set_waiting();
- return m_block_manager.num_free_blocks() > prev_blocks_count;
+ return m_block_manager->num_free_blocks() > prev_blocks_count;
}
static size_t _get_low_priority_sequence_group_id(const std::vector& sequence_groups) {
@@ -212,7 +223,7 @@ class Scheduler {
SequenceGroup::Ptr sequence_group = sequence_groups[sequence_group_id];
// check whether current sequence requires a new slot / block
- while (!m_block_manager.can_append_slots(sequence_group)) {
+ while (!m_block_manager->can_append_slots(sequence_group)) {
// let's run a sequence for eviction
size_t evicted_sequence_group_id = _get_low_priority_sequence_group_id(sequence_groups);
@@ -220,7 +231,7 @@ class Scheduler {
// we have a cycle when current group need to evict itself to be in a running state
break;
}
- size_t blocks_needed = m_block_manager.required_blocks_count(sequence_group);
+ size_t blocks_needed = m_block_manager->required_blocks_count(sequence_group);
if (!_preempt_by_recompute(sequence_groups[evicted_sequence_group_id], blocks_needed)){
break;
}
@@ -259,12 +270,12 @@ class Scheduler {
size_t available_slots = currently_allocated_token_slots - occupied_token_slots,
required_slots = num_scheduled_tokens > available_slots ? num_scheduled_tokens - available_slots : 0;
size_t num_required_blocks = (required_slots + block_size - 1) / block_size;
- while (num_required_blocks > m_block_manager.num_free_blocks()) {
+ while (num_required_blocks > m_block_manager->num_free_blocks()) {
if (!_try_increase_cache()) {
break;
}
}
- size_t num_scheduled_blocks = std::min(num_required_blocks, m_block_manager.num_free_blocks());
+ size_t num_scheduled_blocks = std::min(num_required_blocks, m_block_manager->num_free_blocks());
// some scheduled blocks can be no fully occupied, so we need to take min between num_scheduled_blocks
// and total "scheduled capacity"
num_scheduled_tokens = std::min(num_scheduled_tokens, available_slots + num_scheduled_blocks * block_size);
@@ -272,14 +283,14 @@ class Scheduler {
if (num_scheduled_tokens > 0) {
// allocate KV blocks if required
if (num_scheduled_blocks > 0)
- m_block_manager.allocate(sequence, num_scheduled_blocks, sequence_group->get_prompt_ids());
+ m_block_manager->allocate(sequence, num_scheduled_blocks, sequence_group->get_prompt_ids());
// and schedule tokens
sequence_group->schedule_tokens(num_scheduled_tokens);
// add information to scheduler_output
{
scheduler_output.m_scheduled_sequence_groups_ids.push_back(sequence_group_id);
- scheduler_output.m_block_tables[seq_id] = m_block_manager.get_block_tables(seq_id);
+ scheduler_output.m_block_tables[seq_id] = m_block_manager->get_block_tables(seq_id);
scheduler_output.m_total_num_scheduled_tokens += num_scheduled_tokens * num_running_seqs;
}
}
@@ -291,7 +302,9 @@ class Scheduler {
}
}
- void _schedule_generate_phase_dynamic_split_fuse(const std::vector& sequence_groups, Output& scheduler_output) {
+ void _schedule_generate_phase_dynamic_split_fuse(const std::vector& sequence_groups,
+ Output& scheduler_output,
+ std::map>& block_copy_map) {
for (size_t sequence_group_id = 0; sequence_group_id < sequence_groups.size(); ++sequence_group_id) {
SequenceGroup::Ptr sequence_group = sequence_groups[sequence_group_id];
// Note, that can_generate_tokens will mix preempted sequence groups
@@ -316,7 +329,7 @@ class Scheduler {
size_t num_scheduled_tokens_per_seq = std::min(available_tokens_per_seq_in_megabatch, num_available_tokens_per_seq);
sequence_group->schedule_tokens(num_scheduled_tokens_per_seq);
- while (!m_block_manager.can_append_slots(sequence_group)){
+ while (!m_block_manager->can_append_slots(sequence_group)){
if (!_try_increase_cache()) {
break;
}
@@ -325,13 +338,13 @@ class Scheduler {
_apply_preemption(sequence_group_id, sequence_groups);
// if we can't preemt any more sequences, clear scheduled tokens and move to next sequence
- if (!m_block_manager.can_append_slots(sequence_group)) {
+ if (!m_block_manager->can_append_slots(sequence_group)) {
sequence_group->clear_scheduled_tokens();
continue;
}
// allocate new slots
- std::map> copy_blocks_map = m_block_manager.append_slots(sequence_group);
+ std::map> copy_blocks_map = m_block_manager->append_slots(sequence_group);
// add information to scheduler_output
{
@@ -342,7 +355,7 @@ class Scheduler {
// block tables for each running sequence within a group
std::vector running_seqs = sequence_group->get_running_sequences();
for (const auto & seq : sequence_group->get_running_sequences()) {
- scheduler_output.m_block_tables[seq->get_id()] = m_block_manager.get_block_tables(seq->get_id());
+ scheduler_output.m_block_tables[seq->get_id()] = m_block_manager->get_block_tables(seq->get_id());
}
// merge copy_blocks
@@ -350,7 +363,7 @@ class Scheduler {
size_t src_index = src_dst.first;
const std::list& dst_indexes = src_dst.second;
for (const auto dst_index : dst_indexes)
- scheduler_output.m_block_copy_map[src_index].push_back(dst_index);
+ block_copy_map[src_index].push_back(dst_index);
}
}
@@ -403,12 +416,12 @@ class Scheduler {
// apply KV cache limitations
size_t block_size = get_block_size();
const size_t num_required_blocks = (sequence_len + block_size - 1) / block_size;
- while (!m_block_manager.can_allocate_blocks(num_required_blocks)){
+ while (!m_block_manager->can_allocate_blocks(num_required_blocks)){
if (!_try_increase_cache()) {
break;
}
}
- if (!m_block_manager.can_allocate_blocks(num_required_blocks))
+ if (!m_block_manager->can_allocate_blocks(num_required_blocks))
break;
// add scheduling information
@@ -419,13 +432,13 @@ class Scheduler {
sequence_group->schedule_tokens(sequence_len);
// allocate KV blocks
- m_block_manager.append_slots(sequence_group);
+ m_block_manager->append_slots(sequence_group);
// add information to scheduler_output
{
scheduler_output.m_scheduled_sequence_groups_ids.push_back(sequence_group_id);
uint64_t seq_id = sequence_group->get_running_sequences()[0]->get_id();
- scheduler_output.m_block_tables[seq_id] = m_block_manager.get_block_tables(seq_id);
+ scheduler_output.m_block_tables[seq_id] = m_block_manager->get_block_tables(seq_id);
scheduler_output.m_total_num_scheduled_tokens += sequence_len;
}
@@ -481,7 +494,7 @@ class Scheduler {
auto seq_length = sequence_groups[idx]->get_prompt_len() * m_kv_blocks_initial_multiplier;
auto gen_config = sequence_groups[idx]->get_sampling_parameters();
seq_length = std::min(seq_length, sequence_groups[idx]->get_prompt_len() + gen_config.get_max_new_tokens(sequence_groups[idx]->get_prompt_len()));
- size_t blocks_num = std::ceil((float)seq_length / m_block_manager.get_block_size());
+ size_t blocks_num = std::ceil((float)seq_length / m_block_manager->get_block_size());
if (gen_config.is_beam_search()) {
blocks_num *= gen_config.num_beams;
} else if (gen_config.is_multinomial()) {
@@ -489,7 +502,7 @@ class Scheduler {
}
blocks_sum += blocks_num;
}
- m_block_manager.increase_kv_blocks_number(blocks_sum);
+ m_block_manager->increase_kv_blocks_number(blocks_sum);
m_dynamic_memory_allocation = true;
}
@@ -499,21 +512,21 @@ class Scheduler {
}
auto device_config = m_cache_manager->get_device_config();
auto device = device_config->get_device();
- size_t current_num_of_kv_blocks = m_block_manager.get_total_number_of_kv_blocks();
+ size_t current_num_of_kv_blocks = m_block_manager->get_total_number_of_kv_blocks();
size_t new_blocks_num = current_num_of_kv_blocks * m_cache_growth_factor;
if (device.find("GPU") == std::string::npos) {
- m_block_manager.increase_kv_blocks_number(new_blocks_num);
+ m_block_manager->increase_kv_blocks_number(new_blocks_num);
}
else {
size_t available_gpu_memory = _get_available_gpu_memory();
size_t required_memory = (new_blocks_num - current_num_of_kv_blocks) * device_config->get_block_size_in_bytes();
if (required_memory <= available_gpu_memory) {
- m_block_manager.increase_kv_blocks_number(new_blocks_num);
+ m_block_manager->increase_kv_blocks_number(new_blocks_num);
} else {
size_t possible_blocks_to_add = available_gpu_memory / device_config->get_block_size_in_bytes();
if (possible_blocks_to_add > 0) {
- m_block_manager.increase_kv_blocks_number(current_num_of_kv_blocks + possible_blocks_to_add);
+ m_block_manager->increase_kv_blocks_number(current_num_of_kv_blocks + possible_blocks_to_add);
}
else {
return false;
diff --git a/src/cpp/src/sequence_group.cpp b/src/cpp/src/sequence_group.cpp
index 854fc85777..7b9265db1a 100644
--- a/src/cpp/src/sequence_group.cpp
+++ b/src/cpp/src/sequence_group.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/speculative_decoding/continuous_batching_for_speculative_decoding_impl.cpp b/src/cpp/src/speculative_decoding/continuous_batching_for_speculative_decoding_impl.cpp
index e5468baa9d..dccc633d4d 100644
--- a/src/cpp/src/speculative_decoding/continuous_batching_for_speculative_decoding_impl.cpp
+++ b/src/cpp/src/speculative_decoding/continuous_batching_for_speculative_decoding_impl.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "continuous_batching_for_speculative_decoding_impl.hpp"
diff --git a/src/cpp/src/speculative_decoding/continuous_batching_for_speculative_decoding_impl.hpp b/src/cpp/src/speculative_decoding/continuous_batching_for_speculative_decoding_impl.hpp
index 4d476b8cbc..3777d9b87b 100644
--- a/src/cpp/src/speculative_decoding/continuous_batching_for_speculative_decoding_impl.hpp
+++ b/src/cpp/src/speculative_decoding/continuous_batching_for_speculative_decoding_impl.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/speculative_decoding/speculative_decoding_impl.cpp b/src/cpp/src/speculative_decoding/speculative_decoding_impl.cpp
index 8b2730a62b..5483523698 100644
--- a/src/cpp/src/speculative_decoding/speculative_decoding_impl.cpp
+++ b/src/cpp/src/speculative_decoding/speculative_decoding_impl.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "text_callback_streamer.hpp"
diff --git a/src/cpp/src/speculative_decoding/speculative_decoding_impl.hpp b/src/cpp/src/speculative_decoding/speculative_decoding_impl.hpp
index b84b5b8590..7475d9d766 100644
--- a/src/cpp/src/speculative_decoding/speculative_decoding_impl.hpp
+++ b/src/cpp/src/speculative_decoding/speculative_decoding_impl.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/speculative_decoding/speculative_decoding_metrics.cpp b/src/cpp/src/speculative_decoding/speculative_decoding_metrics.cpp
index 4e5602482a..2357b99fd7 100644
--- a/src/cpp/src/speculative_decoding/speculative_decoding_metrics.cpp
+++ b/src/cpp/src/speculative_decoding/speculative_decoding_metrics.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/speculative_decoding/speculative_decoding_metrics.hpp b/src/cpp/src/speculative_decoding/speculative_decoding_metrics.hpp
index 0d9173b99f..d4a14a1692 100644
--- a/src/cpp/src/speculative_decoding/speculative_decoding_metrics.hpp
+++ b/src/cpp/src/speculative_decoding/speculative_decoding_metrics.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/speculative_decoding/update_request_structs.hpp b/src/cpp/src/speculative_decoding/update_request_structs.hpp
index bd9bb3b67e..68f79268f5 100644
--- a/src/cpp/src/speculative_decoding/update_request_structs.hpp
+++ b/src/cpp/src/speculative_decoding/update_request_structs.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/synchronized_queue.hpp b/src/cpp/src/synchronized_queue.hpp
index 55649a7032..70883bcae7 100644
--- a/src/cpp/src/synchronized_queue.hpp
+++ b/src/cpp/src/synchronized_queue.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/text_callback_streamer.cpp b/src/cpp/src/text_callback_streamer.cpp
index 5938b55f6c..4c4db4311f 100644
--- a/src/cpp/src/text_callback_streamer.cpp
+++ b/src/cpp/src/text_callback_streamer.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "text_callback_streamer.hpp"
@@ -15,23 +15,36 @@ bool TextCallbackStreamer::put(int64_t token) {
std::stringstream res;
m_tokens_cache.push_back(token);
std::string text = m_tokenizer.decode(m_tokens_cache);
- if (!text.empty() && '\n' == text.back() && text.size() > print_len) {
+ m_decoded_lengths.push_back(text.length());
+
+ if (!text.empty() && '\n' == text.back() && text.size() > m_printed_len) {
// Flush the cache after the new line symbol
- res << std::string_view{text.data() + print_len, text.size() - print_len};
+ res << std::string_view{text.data() + m_printed_len, text.size() - m_printed_len};
m_tokens_cache.clear();
- print_len = 0;
+ m_decoded_lengths.clear();
+ m_printed_len = 0;
return on_finalized_subword_callback(res.str());
}
+ constexpr size_t delay_n_tokens = 3;
+ // In some cases adding the next token can shorten the text,
+ // e.g. when apostrophe removing regex had worked after adding new tokens.
+ // Printing several last tokens is delayed.
+ if (m_decoded_lengths.size() < delay_n_tokens) {
+ return on_finalized_subword_callback(res.str());
+ }
constexpr char replacement[] = "\xef\xbf\xbd"; // MSVC with /utf-8 fails to compile � directly with newline in string literal error.
if (text.size() >= 3 && text.compare(text.size() - 3, 3, replacement) == 0) {
+ m_decoded_lengths[m_decoded_lengths.size() - 1] = -1;
// Don't print incomplete text
return on_finalized_subword_callback(res.str());
- } else if (text.size() > print_len) {
+ }
+ auto print_until = m_decoded_lengths[m_decoded_lengths.size() - delay_n_tokens];
+ if (print_until != -1 && print_until > m_printed_len) {
// It is possible to have a shorter text after adding new token.
// Print to output only if text length is increaesed.
- res << std::string_view{text.data() + print_len, text.size() - print_len} << std::flush;
- print_len = text.size();
+ res << std::string_view{text.data() + m_printed_len, print_until - m_printed_len} << std::flush;
+ m_printed_len = print_until;
}
return on_finalized_subword_callback(res.str());
@@ -40,11 +53,12 @@ bool TextCallbackStreamer::put(int64_t token) {
void TextCallbackStreamer::end() {
std::stringstream res;
std::string text = m_tokenizer.decode(m_tokens_cache);
- if (text.size() <= print_len)
- return ;
- res << std::string_view{text.data() + print_len, text.size() - print_len} << std::flush;
+ if (text.size() <= m_printed_len)
+ return;
+ res << std::string_view{text.data() + m_printed_len, text.size() - m_printed_len} << std::flush;
m_tokens_cache.clear();
- print_len = 0;
+ m_decoded_lengths.clear();
+ m_printed_len = 0;
on_finalized_subword_callback(res.str());
return;
}
diff --git a/src/cpp/src/text_callback_streamer.hpp b/src/cpp/src/text_callback_streamer.hpp
index 6f0872ad1b..2c5fab5700 100644
--- a/src/cpp/src/text_callback_streamer.hpp
+++ b/src/cpp/src/text_callback_streamer.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -21,7 +21,8 @@ class TextCallbackStreamer: public StreamerBase {
protected:
Tokenizer m_tokenizer;
std::vector m_tokens_cache;
- size_t print_len = 0;
+ std::vector m_decoded_lengths;
+ size_t m_printed_len = 0;
};
} // namespace genai
diff --git a/src/cpp/src/timer.hpp b/src/cpp/src/timer.hpp
index de23e56f60..f389e10d5d 100644
--- a/src/cpp/src/timer.hpp
+++ b/src/cpp/src/timer.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/tokenizer.cpp b/src/cpp/src/tokenizer.cpp
index 03e3b0a5d3..b22f103577 100644
--- a/src/cpp/src/tokenizer.cpp
+++ b/src/cpp/src/tokenizer.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
@@ -575,13 +575,18 @@ class Tokenizer::TokenizerImpl {
{"slice", slice_callable},
};
+ std::string result;
try {
- return tpl.RenderAsString(params).value();
+ result = tpl.RenderAsString(params).value();
} catch (const std::exception& error) {
OPENVINO_THROW("Chat template for the current model is not supported by Jinja2Cpp. "
"Please apply template manually to your prompt before calling generate. "
"For example: user{user_prompt}model");
}
+ OPENVINO_ASSERT(!result.empty(), "Applied chat template resulted in an empty string. "
+ "Please check the chat template or apply template manually to your prompt before calling generate."
+ "For example: user{user_prompt}model");
+ return result;
}
void set_chat_template(const std::string& chat_template) {
diff --git a/src/cpp/src/utils.cpp b/src/cpp/src/utils.cpp
index 9261aa7a4a..5b17b2eacf 100644
--- a/src/cpp/src/utils.cpp
+++ b/src/cpp/src/utils.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "utils.hpp"
diff --git a/src/cpp/src/utils.hpp b/src/cpp/src/utils.hpp
index ad0e1a05d4..ff1aea1ae9 100644
--- a/src/cpp/src/utils.hpp
+++ b/src/cpp/src/utils.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/utils/paged_attention_transformations.cpp b/src/cpp/src/utils/paged_attention_transformations.cpp
index f564be8f19..baef7d8dd6 100644
--- a/src/cpp/src/utils/paged_attention_transformations.cpp
+++ b/src/cpp/src/utils/paged_attention_transformations.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "utils/paged_attention_transformations.hpp"
diff --git a/src/cpp/src/utils/paged_attention_transformations.hpp b/src/cpp/src/utils/paged_attention_transformations.hpp
index 2cb32adcdc..c21b06a6f5 100644
--- a/src/cpp/src/utils/paged_attention_transformations.hpp
+++ b/src/cpp/src/utils/paged_attention_transformations.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/visual_language/clip.cpp b/src/cpp/src/visual_language/clip.cpp
index fba8b10d4f..30a6dff5ae 100644
--- a/src/cpp/src/visual_language/clip.cpp
+++ b/src/cpp/src/visual_language/clip.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
// Based on clip.cpp
diff --git a/src/cpp/src/visual_language/clip.hpp b/src/cpp/src/visual_language/clip.hpp
index 55cf03a49f..4bdb4542d0 100644
--- a/src/cpp/src/visual_language/clip.hpp
+++ b/src/cpp/src/visual_language/clip.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/visual_language/embedding_model.cpp b/src/cpp/src/visual_language/embedding_model.cpp
index a2a9750c33..ebc2f80bbd 100644
--- a/src/cpp/src/visual_language/embedding_model.cpp
+++ b/src/cpp/src/visual_language/embedding_model.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/visual_language/inputs_embedder.cpp b/src/cpp/src/visual_language/inputs_embedder.cpp
index 9f228cafa3..4f3812862c 100644
--- a/src/cpp/src/visual_language/inputs_embedder.cpp
+++ b/src/cpp/src/visual_language/inputs_embedder.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/visual_language/perf_metrics.hpp"
@@ -52,6 +52,12 @@ class InputsEmbedder::IInputsEmbedder {
public:
virtual ov::Tensor get_inputs_embeds(const std::string& prompt, const std::vector& images, ov::genai::VLMPerfMetrics& metrics) = 0;
+ virtual std::pair> get_position_ids(const size_t inputs_embeds_size, const size_t history_size) {
+ ov::Tensor position_ids = ov::Tensor{ov::element::i64, { 1, inputs_embeds_size }};
+ std::iota(position_ids.data(), position_ids.data() + position_ids.get_size(), history_size);
+ return {position_ids, std::nullopt};
+ }
+
EmbeddingsModel get_embedding_model() const {
return m_embedding;
}
@@ -1157,6 +1163,408 @@ class InputsEmbedderInternVLChat : public InputsEmbedder::IInputsEmbedder {
}
};
+class InputsEmbedderQwen2VL : public InputsEmbedder::IInputsEmbedder {
+ // A model for merging image embeddings (hidden states), rotary_pos_emb and attension_mask.
+ // Inputs:
+ // - hidden_states: [N, embed_dim]
+ // - rotary_pos_emb: [?, 40]
+ // - attention_mask: [1, ?, ?]
+ // Output: [N, hidden_size]
+ ov::InferRequest m_vision_embeddings_merger;
+
+ ov::Tensor m_position_ids;
+ int64_t m_rope_delta = 0;
+
+public:
+ InputsEmbedderQwen2VL(
+ const VLMConfig& vlm_config,
+ const std::filesystem::path& model_dir,
+ const std::string& device,
+ const ov::AnyMap device_config) :
+ IInputsEmbedder(vlm_config, model_dir, device, device_config) {
+ auto compiled_model = utils::singleton_core().compile_model(model_dir / "openvino_vision_embeddings_merger_model.xml", device, device_config);
+ ov::genai::utils::print_compiled_model_properties(compiled_model, "VLM vision embeddings merger model");
+ m_vision_embeddings_merger = compiled_model.create_infer_request();
+ }
+
+ InputsEmbedderQwen2VL(
+ const VLMConfig& vlm_config,
+ const ModelsMap& models_map,
+ const Tokenizer& tokenizer,
+ const std::filesystem::path& config_dir_path,
+ const std::string& device,
+ const ov::AnyMap device_config) :
+ IInputsEmbedder(vlm_config, models_map, tokenizer, config_dir_path, device, device_config) {
+ m_vision_embeddings_merger = utils::singleton_core().compile_model(
+ get_model_weights_pair(models_map, "vision_embeddings_merger").first,
+ get_model_weights_pair(models_map, "vision_embeddings_merger").second,
+ device,
+ device_config
+ ).create_infer_request();
+ }
+
+ virtual ov::Tensor get_inputs_embeds(const std::string& prompt, const std::vector& images, ov::genai::VLMPerfMetrics& metrics) override {
+ std::string formatted_prompt;
+
+ std::vector single_images = to_single_image_tensors(images);
+ std::vector image_embeds;
+ std::vector> images_grid_thw;
+ image_embeds.reserve(single_images.size());
+ images_grid_thw.reserve(single_images.size());
+
+ for (const auto& image : single_images) {
+ EncodedImage encoded_image = m_vision_encoder.encode(image);
+ ov::Tensor single_image_embeds = encoded_image.resized_source;
+ image_embeds.push_back(std::move(single_image_embeds));
+
+ size_t grid_t = 1;
+ size_t grid_h = encoded_image.resized_source_size.height;
+ size_t grid_w = encoded_image.resized_source_size.width;
+ images_grid_thw.push_back({grid_t, grid_h, grid_w});
+
+ size_t merge_length = std::pow(m_vision_encoder.m_processor_config.merge_size, 2);
+ size_t num_image_pad_tokens = grid_t * grid_h * grid_w / merge_length;
+
+ formatted_prompt += m_vlm_config.vision_start_token;
+ for (int i = 0; i < num_image_pad_tokens; i++) {
+ formatted_prompt += m_vlm_config.image_pad_token;
+ }
+ formatted_prompt += m_vlm_config.vision_end_token;
+ }
+ formatted_prompt += prompt;
+
+ // Adapted from Qwen/Qwen2-7B-Instruct
+ std::string chat_template_fallback = "{% for message in messages %}{% if loop.first and messages[0]['role'] != 'system' %}{{ '<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n' }}{% endif %}{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}{% endfor %}{% if add_generation_prompt %}{{ '<|im_start|>assistant\n' }}{% endif %}";
+ ov::Tensor input_ids = get_encoded_input_ids(formatted_prompt, metrics, chat_template_fallback);
+ ov::Tensor text_embeds = m_embedding.infer(input_ids);
+
+ if (images.empty()) {
+ return text_embeds;
+ }
+
+ auto start_tokenizer_time = std::chrono::steady_clock::now();
+ ov::Tensor encoded_vision_start_token = m_tokenizer.encode(m_vlm_config.vision_start_token, ov::genai::add_special_tokens(false)).input_ids;
+ ov::Tensor encoded_image_pad_token = m_tokenizer.encode(m_vlm_config.image_pad_token, ov::genai::add_special_tokens(false)).input_ids;
+ auto end_tokenizer_time = std::chrono::steady_clock::now();
+ OPENVINO_ASSERT(metrics.raw_metrics.tokenization_durations.size() > 0);
+ metrics.raw_metrics.tokenization_durations[metrics.raw_metrics.tokenization_durations.size() - 1] += ov::genai::MicroSeconds(PerfMetrics::get_microsec(end_tokenizer_time - start_tokenizer_time));
+ int64_t vision_start_token_id = encoded_vision_start_token.data()[encoded_vision_start_token.get_size() - 1];
+ int64_t image_pad_token_id = encoded_image_pad_token.data()[encoded_image_pad_token.get_size() - 1];
+
+ m_position_ids = create_position_ids(input_ids, images_grid_thw, vision_start_token_id);
+
+ int64_t position_ids_max_element = *std::max_element(m_position_ids.data(), m_position_ids.data() + m_position_ids.get_size());
+ m_rope_delta = position_ids_max_element + 1 - static_cast(input_ids.get_shape().at(1));
+
+ return merge_text_and_image_embeddings_qwen2vl(input_ids, text_embeds, image_embeds, images_grid_thw, image_pad_token_id);
+ }
+
+ virtual std::pair> get_position_ids(const size_t inputs_embeds_size, const size_t history_size) override {
+ if (history_size != 0) {
+ ov::Tensor position_ids{ov::element::i64, {3, 1, inputs_embeds_size}};
+ int64_t new_pos_id = static_cast(history_size + m_rope_delta);
+ for (size_t dim = 0; dim < 3; ++dim) {
+ int64_t* pos_data = position_ids.data() + dim * inputs_embeds_size;
+ std::iota(pos_data, pos_data + inputs_embeds_size, new_pos_id);
+ }
+ return {position_ids, m_rope_delta};
+ }
+ return {m_position_ids, m_rope_delta};
+ }
+
+ virtual void start_chat(const std::string& system_message) override {
+ IInputsEmbedder::start_chat(system_message);
+ m_position_ids = ov::Tensor();
+ m_rope_delta = 0;
+ }
+
+ virtual void finish_chat() override {
+ IInputsEmbedder::finish_chat();
+ m_position_ids = ov::Tensor();
+ m_rope_delta = 0;
+ }
+protected:
+ ov::Tensor merge_text_and_image_embeddings_qwen2vl(
+ const ov::Tensor& input_ids,
+ const ov::Tensor& text_embeds,
+ const std::vector& image_embeds,
+ const std::vector> images_grid_thw,
+ const int64_t image_pad_token_id
+ ) {
+ // Calculate cumulative sequence lengths for attention mask
+ std::vector cu_seqlens;
+ cu_seqlens.push_back(0);
+ int32_t cumsum = 0;
+ for (const auto& grid_thw : images_grid_thw) {
+ size_t slice_len = grid_thw.at(1) * grid_thw.at(2);
+ for (size_t t = 0; t < grid_thw.at(0); ++t) {
+ cumsum += slice_len;
+ cu_seqlens.push_back(cumsum);
+ }
+ }
+
+ // Create attention mask for vision embeddings merger model
+ size_t hidden_states_size = cumsum;
+ ov::Tensor attention_mask{ov::element::f32, {1, hidden_states_size, hidden_states_size}};
+ float* attention_mask_data = attention_mask.data();
+ std::fill_n(attention_mask_data, attention_mask.get_size(), -std::numeric_limits::infinity());
+
+ for (size_t i = 1; i < cu_seqlens.size(); ++i) {
+ size_t start = cu_seqlens[i-1];
+ size_t end = cu_seqlens[i];
+ for (size_t row = start; row < end; ++row) {
+ for (size_t col = start; col < end; ++col) {
+ attention_mask_data[row * hidden_states_size + col] = 0.0f;
+ }
+ }
+ }
+
+ // Concatenate image embeddings
+ ov::Tensor concatenated_images;
+ if (image_embeds.size() == 1) {
+ concatenated_images = image_embeds.at(0);
+ } else {
+ size_t total_length = 0;
+ for (const auto& embed : image_embeds) {
+ total_length += embed.get_shape().at(0);
+ }
+ size_t hidden_dim = image_embeds.at(0).get_shape().at(1);
+
+ concatenated_images = ov::Tensor(image_embeds.at(0).get_element_type(), {total_length, hidden_dim});
+ float* concat_data = concatenated_images.data();
+
+ size_t offset = 0;
+ for (const auto& embed : image_embeds) {
+ size_t embed_size = embed.get_shape().at(0) * embed.get_shape().at(1);
+ std::memcpy(concat_data + offset, embed.data(), embed.get_byte_size());
+ offset += embed_size;
+ }
+ }
+
+ ov::Tensor rotary_pos_emb = get_rotary_pos_emb(images_grid_thw);
+
+ m_vision_embeddings_merger.set_tensor("hidden_states", concatenated_images);
+ m_vision_embeddings_merger.set_tensor("attention_mask", attention_mask);
+ m_vision_embeddings_merger.set_tensor("rotary_pos_emb", rotary_pos_emb);
+ m_vision_embeddings_merger.infer();
+ ov::Tensor processed_vision_embeds = m_vision_embeddings_merger.get_output_tensor();
+
+ ov::Tensor merged_embeds(text_embeds.get_element_type(), text_embeds.get_shape());
+ std::memcpy(merged_embeds.data(), text_embeds.data(), text_embeds.get_byte_size());
+
+ auto text_embeds_shape = text_embeds.get_shape();
+ size_t batch_size = text_embeds_shape.at(0);
+ size_t seq_length = text_embeds_shape.at(1);
+ size_t hidden_size = text_embeds_shape.at(2);
+
+ const int64_t* input_ids_data = input_ids.data();
+ float* merged_embeds_data = merged_embeds.data();
+ const float* vision_embeds_data = processed_vision_embeds.data();
+
+ size_t vision_embed_idx = 0;
+ for (size_t batch_idx = 0; batch_idx < batch_size; ++batch_idx) {
+ for (size_t seq_idx = 0; seq_idx < seq_length; ++seq_idx) {
+ size_t flat_idx = batch_idx * seq_length + seq_idx;
+ if (input_ids_data[flat_idx] == image_pad_token_id) {
+ std::copy_n(
+ vision_embeds_data + vision_embed_idx * hidden_size,
+ hidden_size,
+ merged_embeds_data + flat_idx * hidden_size
+ );
+ ++vision_embed_idx;
+ }
+ }
+ }
+ return merged_embeds;
+ }
+
+ ov::Tensor get_rotary_pos_emb(const std::vector>& grids_thw) {
+ const size_t spatial_merge_size = m_vision_encoder.m_processor_config.merge_size;
+
+ std::vector> all_pos_ids;
+ size_t total_positions = 0;
+ size_t max_grid_size = 0;
+
+ for (const auto& grid_thw : grids_thw) {
+ size_t t = grid_thw.at(0);
+ size_t h = grid_thw.at(1);
+ size_t w = grid_thw.at(2);
+
+ total_positions += t * h * w;
+ max_grid_size = std::max({max_grid_size, h, w});
+
+ // Create height position IDs
+ std::vector hpos_ids(h * w);
+ for (size_t hi = 0; hi < h; ++hi) {
+ for (size_t wi = 0; wi < w; ++wi) {
+ size_t idx = hi * w + wi;
+ hpos_ids[idx] = hi;
+ }
+ }
+
+ // Reshape hpos_ids according to spatial merge size
+ std::vector reshaped_hpos;
+ size_t h_blocks = h / spatial_merge_size;
+ size_t w_blocks = w / spatial_merge_size;
+ reshaped_hpos.reserve(h * w);
+
+ for (size_t hb = 0; hb < h_blocks; ++hb) {
+ for (size_t wb = 0; wb < w_blocks; ++wb) {
+ for (size_t hs = 0; hs < spatial_merge_size; ++hs) {
+ for (size_t ws = 0; ws < spatial_merge_size; ++ws) {
+ reshaped_hpos.push_back(hb * spatial_merge_size + hs);
+ }
+ }
+ }
+ }
+
+ // Create width position IDs
+ std::vector wpos_ids(h * w);
+ for (size_t hi = 0; hi < h; ++hi) {
+ for (size_t wi = 0; wi < w; ++wi) {
+ size_t idx = hi * w + wi;
+ wpos_ids[idx] = wi;
+ }
+ }
+
+ // Reshape wpos_ids according to spatial merge size
+ std::vector reshaped_wpos;
+ reshaped_wpos.reserve(h * w);
+
+ for (size_t hb = 0; hb < h_blocks; ++hb) {
+ for (size_t wb = 0; wb < w_blocks; ++wb) {
+ for (size_t hs = 0; hs < spatial_merge_size; ++hs) {
+ for (size_t ws = 0; ws < spatial_merge_size; ++ws) {
+ reshaped_wpos.push_back(wb * spatial_merge_size + ws);
+ }
+ }
+ }
+ }
+
+ // Stack and repeat for each t
+ for (size_t i = 0; i < t; ++i) {
+ for (size_t j = 0; j < reshaped_hpos.size(); ++j) {
+ all_pos_ids.push_back({reshaped_hpos[j], reshaped_wpos[j]});
+ }
+ }
+ }
+
+ // Calculate rotary embeddings for max_grid_size
+ const size_t dim = 1280 / 16 / 2; // config.vision_config.embed_dim / self.config.vision_config.num_heads / 2
+ const float theta = 10000.0f;
+
+ std::vector inv_freq(dim / 2);
+ for (size_t i = 0; i < dim / 2; ++i) {
+ inv_freq[i] = 1.0f / std::pow(theta, static_cast(i) / static_cast(dim / 2));
+ }
+
+ std::vector> freqs(max_grid_size);
+ for (size_t i = 0; i < max_grid_size; ++i) {
+ freqs[i].resize(dim / 2);
+ for (size_t j = 0; j < dim / 2; ++j) {
+ freqs[i][j] = static_cast(i) * inv_freq[j];
+ }
+ }
+
+ ov::Tensor rotary_pos_emb(ov::element::f32, {all_pos_ids.size(), dim});
+ float* output_data = rotary_pos_emb.data();
+
+ for (size_t i = 0; i < all_pos_ids.size(); ++i) {
+ const auto& pos = all_pos_ids.at(i);
+ size_t h_idx = pos.at(0);
+ size_t w_idx = pos.at(1);
+ std::copy_n(freqs[h_idx].begin(), dim / 2, output_data + i * dim);
+ std::copy_n(freqs[w_idx].begin(), dim / 2, output_data + i * dim + dim / 2);
+ }
+
+ return rotary_pos_emb;
+ }
+
+ ov::Tensor create_position_ids(
+ const ov::Tensor& input_ids_tensor,
+ const std::vector>& images_grid_thw,
+ const int64_t vision_start_token_id
+ ) {
+ const size_t spatial_merge_size = m_vision_encoder.m_processor_config.merge_size;
+
+ const int64_t* input_ids = input_ids_tensor.data();
+ size_t batch_size = input_ids_tensor.get_shape().at(0);
+ size_t seq_len = input_ids_tensor.get_shape().at(1);
+
+ std::vector vision_start_indices;
+ for (size_t i = 0; i < seq_len; ++i) {
+ if (input_ids[i] == vision_start_token_id) {
+ vision_start_indices.push_back(i);
+ }
+ }
+
+ ov::Tensor position_ids{ov::element::i64, {3, batch_size, seq_len}};
+ int64_t* pos_data = position_ids.data();
+
+ size_t st = 0;
+ int64_t next_pos = 0;
+ size_t grid_idx = 0;
+
+ for (size_t i = 0; i < vision_start_indices.size(); ++i) {
+ size_t ed = vision_start_indices.at(i);
+
+ // Process text tokens before image
+ if (st < ed) {
+ for (size_t pos = st; pos < ed; ++pos) {
+ pos_data[pos] = next_pos; // temporal
+ pos_data[seq_len + pos] = next_pos; // height
+ pos_data[2 * seq_len + pos] = next_pos; // width
+ next_pos++;
+ }
+ }
+
+ // Process image start token
+ pos_data[ed] = next_pos; // temporal
+ pos_data[seq_len + ed] = next_pos; // height
+ pos_data[2 * seq_len + ed] = next_pos; // width
+ next_pos++;
+ ed++;
+
+ // Process image token with grid
+ if (grid_idx < images_grid_thw.size()) {
+ const auto& grid = images_grid_thw.at(grid_idx);
+ size_t llm_grid_h = grid.at(1) / spatial_merge_size;
+ size_t llm_grid_w = grid.at(2) / spatial_merge_size;
+ size_t ed_image = ed + llm_grid_h * llm_grid_w;
+
+ // Fill temporal dimension
+ std::fill_n(pos_data + ed, llm_grid_h * llm_grid_w, next_pos);
+
+ // Fill height and width dimensions
+ int64_t* height_data = pos_data + seq_len + ed;
+ int64_t* width_data = pos_data + 2 * seq_len + ed;
+ for (size_t h = 0; h < llm_grid_h; ++h) {
+ std::fill_n(height_data + h * llm_grid_w, llm_grid_w, next_pos + h);
+ for (size_t w = 0; w < llm_grid_w; ++w) {
+ width_data[h * llm_grid_w + w] = next_pos + w;
+ }
+ }
+
+ next_pos += std::max(llm_grid_h, llm_grid_w);
+ st = ed_image;
+ grid_idx++;
+ }
+ }
+
+ // Process remaining text tokens
+ if (st < seq_len) {
+ for (size_t pos = st; pos < seq_len; ++pos) {
+ pos_data[pos] = next_pos; // temporal
+ pos_data[seq_len + pos] = next_pos; // height
+ pos_data[2 * seq_len + pos] = next_pos; // width
+ next_pos++;
+ }
+ }
+
+ return position_ids;
+ }
+};
+
InputsEmbedder::InputsEmbedder(const VLMConfig& vlm_config,
const std::filesystem::path& model_dir,
const std::string& device,
@@ -1169,6 +1577,8 @@ InputsEmbedder::InputsEmbedder(const VLMConfig& vlm_config,
m_impl = std::make_shared(vlm_config, model_dir, device, device_config);
} else if (vlm_config.model_type == VLMModelType::INTERNVL_CHAT) {
m_impl = std::make_shared(vlm_config, model_dir, device, device_config);
+ } else if (vlm_config.model_type == VLMModelType::QWEN2_VL) {
+ m_impl = std::make_shared(vlm_config, model_dir, device, device_config);
} else {
OPENVINO_THROW("Unsupported model type in VLM InputsEmbedder class. Please, create feature request on new model support");
}
@@ -1188,6 +1598,8 @@ InputsEmbedder::InputsEmbedder(const VLMConfig& vlm_config,
m_impl = std::make_shared(vlm_config, models_map, tokenizer, config_dir_path, device, device_config);
} else if (vlm_config.model_type == VLMModelType::INTERNVL_CHAT) {
m_impl = std::make_shared(vlm_config, models_map, tokenizer, config_dir_path, device, device_config);
+ } else if (vlm_config.model_type == VLMModelType::QWEN2_VL) {
+ m_impl = std::make_shared(vlm_config, models_map, tokenizer, config_dir_path, device, device_config);
} else {
OPENVINO_THROW("Unsupported model type in VLM InputsEmbedder class. Please, create feature request on new model support");
}
@@ -1197,6 +1609,10 @@ ov::Tensor InputsEmbedder::get_inputs_embeds(const std::string& prompt, const st
return m_impl->get_inputs_embeds(prompt, images, metrics);
}
+std::pair> InputsEmbedder::get_position_ids(const size_t inputs_embeds_size, const size_t history_size) {
+ return m_impl->get_position_ids(inputs_embeds_size, history_size);
+}
+
EmbeddingsModel InputsEmbedder::get_embedding_model() const {
return m_impl->get_embedding_model();
}
diff --git a/src/cpp/src/visual_language/inputs_embedder.hpp b/src/cpp/src/visual_language/inputs_embedder.hpp
index 1d72b742ab..223d090b22 100644
--- a/src/cpp/src/visual_language/inputs_embedder.hpp
+++ b/src/cpp/src/visual_language/inputs_embedder.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -34,6 +34,9 @@ class InputsEmbedder {
// compute input embedding for prompt and multiple images
ov::Tensor get_inputs_embeds(const std::string& prompt, const std::vector& images, ov::genai::VLMPerfMetrics& metrics);
+ // compute position ids for language model input
+ std::pair> get_position_ids(const size_t inputs_embeds_size, const size_t history_size);
+
// returns embedding model which converts token_id(s) to embedding vectors
EmbeddingsModel get_embedding_model() const;
@@ -65,6 +68,7 @@ class InputsEmbedder {
friend class InputsEmbedderLLaVA;
friend class InputsEmbedderLLaVANext;
friend class InputsEmbedderInternVLChat;
+ friend class InputsEmbedderQwen2VL;
};
} // namespace ov::genai
diff --git a/src/cpp/src/visual_language/perf_metrics.cpp b/src/cpp/src/visual_language/perf_metrics.cpp
index a3afb83641..a5894078bf 100644
--- a/src/cpp/src/visual_language/perf_metrics.cpp
+++ b/src/cpp/src/visual_language/perf_metrics.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/visual_language/perf_metrics.hpp"
diff --git a/src/cpp/src/visual_language/pipeline.cpp b/src/cpp/src/visual_language/pipeline.cpp
index ebc5c3b5dd..95e3064548 100644
--- a/src/cpp/src/visual_language/pipeline.cpp
+++ b/src/cpp/src/visual_language/pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
@@ -208,8 +208,9 @@ class ov::genai::VLMPipeline::VLMPipelineImpl {
ov::Tensor new_atten_mask = ov::Tensor{ov::element::i64, { 1, history_size + inputs_embeds_size }};
std::fill_n(new_atten_mask.data(), new_atten_mask.get_size(), 1);
- ov::Tensor position_ids = ov::Tensor{ov::element::i64, { 1, inputs_embeds_size }};
- std::iota(position_ids.data(), position_ids.data() + position_ids.get_size(), history_size);
+ ov::Tensor position_ids;
+ std::optional rope_delta;
+ std::tie(position_ids, rope_delta) = m_inputs_embedder->get_position_ids(inputs_embeds_size, history_size);
if (m_sampler.get_seed() != generation_config.rng_seed) {
m_sampler.set_seed(generation_config.rng_seed);
@@ -218,7 +219,7 @@ class ov::genai::VLMPipeline::VLMPipelineImpl {
ov::genai::EncodedResults encoded_result;
std::optional last_disappeared_token;
std::tie(encoded_result, last_disappeared_token) = ov::genai::get_lm_encoded_results(m_language, inputs_embeds, new_atten_mask, streamer_ptr, m_sampler, requests,
- position_ids, m_embedding);
+ position_ids, m_embedding, rope_delta);
auto decode_start_time = std::chrono::steady_clock::now();
VLMDecodedResults decoded;
diff --git a/src/cpp/src/visual_language/processor_config.cpp b/src/cpp/src/visual_language/processor_config.cpp
index fc524fce9c..f790c58912 100644
--- a/src/cpp/src/visual_language/processor_config.cpp
+++ b/src/cpp/src/visual_language/processor_config.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "processor_config.hpp"
@@ -33,7 +33,7 @@ ov::genai::ProcessorConfig::ProcessorConfig(const std::filesystem::path& json_pa
crop_size_height = parsed.at("crop_size").at("height");
crop_size_width = parsed.at("crop_size").at("width");
}
- if (parsed.contains("size")) {
+ if (parsed.contains("size") && parsed.at("size").contains("shortest_edge")) {
size_shortest_edge = parsed.at("size").at("shortest_edge");
}
@@ -41,4 +41,10 @@ ov::genai::ProcessorConfig::ProcessorConfig(const std::filesystem::path& json_pa
if (parsed.contains("image_grid_pinpoints")) {
image_grid_pinpoints = parsed.at("image_grid_pinpoints").get>>();
}
+
+ // Setting qwen2vl config params
+ read_json_param(parsed, "min_pixels", min_pixels);
+ read_json_param(parsed, "max_pixels", max_pixels);
+ read_json_param(parsed, "temporal_patch_size", temporal_patch_size);
+ read_json_param(parsed, "merge_size", merge_size);
}
diff --git a/src/cpp/src/visual_language/processor_config.hpp b/src/cpp/src/visual_language/processor_config.hpp
index 83cf9870a3..1d40e091a9 100644
--- a/src/cpp/src/visual_language/processor_config.hpp
+++ b/src/cpp/src/visual_language/processor_config.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -45,6 +45,12 @@ class ProcessorConfig {
// llava-next specific config params
std::vector> image_grid_pinpoints{{336, 672}, {672, 336}, {672, 672}, {1008, 336}, {336, 1008}};
+ // qwen2vl specific params
+ size_t min_pixels = 3136;
+ size_t max_pixels = 12845056;
+ size_t temporal_patch_size = 2;
+ size_t merge_size = 2;
+
/// @brief Default constructor
ProcessorConfig() = default;
/// @brief Construct ProcessorConfig from values in json_path.
diff --git a/src/cpp/src/visual_language/vision_encoder.cpp b/src/cpp/src/visual_language/vision_encoder.cpp
index 9f8f9b0498..4a5179fdd0 100644
--- a/src/cpp/src/visual_language/vision_encoder.cpp
+++ b/src/cpp/src/visual_language/vision_encoder.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "vision_encoder.hpp"
@@ -644,6 +644,158 @@ ov::Tensor get_pixel_values_internvl(const ov::Tensor& image, const ProcessorCon
}
return output_tensor;
}
+
+ImageSize smart_resize_qwen2vl(size_t height, size_t width, size_t factor, size_t min_pixels, size_t max_pixels) {
+ if (height < factor || width < factor) {
+ OPENVINO_THROW("Height or width must be larger than factor");
+ }
+ if (std::max(height, width) / std::min(height, width) > 200) {
+ OPENVINO_THROW("Absolute aspect ratio must be smaller than 200");
+ }
+
+ size_t h_bar = std::round(static_cast(height) / factor) * factor;
+ size_t w_bar = std::round(static_cast(width) / factor) * factor;
+
+ if (h_bar * w_bar > max_pixels) {
+ double beta = std::sqrt((height * width) / static_cast(max_pixels));
+ h_bar = std::floor(height / beta / factor) * factor;
+ w_bar = std::floor(width / beta / factor) * factor;
+ } else if (h_bar * w_bar < min_pixels) {
+ double beta = std::sqrt(min_pixels / static_cast(height * width));
+ h_bar = std::ceil(height * beta / factor) * factor;
+ w_bar = std::ceil(width * beta / factor) * factor;
+ }
+
+ return ImageSize{h_bar, w_bar};
+}
+
+ov::Tensor reshape_image_patches_qwen2vl(
+ const ov::Tensor& patches,
+ const size_t grid_t,
+ const size_t grid_h,
+ const size_t grid_w,
+ const size_t channel,
+ const size_t temporal_patch_size,
+ const size_t patch_size,
+ const size_t spatial_merge_size
+) {
+ ov::Shape output_shape{
+ grid_t,
+ temporal_patch_size,
+ channel,
+ grid_h / spatial_merge_size,
+ spatial_merge_size,
+ patch_size,
+ grid_w / spatial_merge_size,
+ spatial_merge_size,
+ patch_size
+ };
+
+ ov::Tensor reshaped_patches(patches.get_element_type(), output_shape);
+
+ const float* input_data = patches.data();
+ float* output_data = reshaped_patches.data();
+
+ size_t input_idx = 0;
+
+ for (size_t gt = 0; gt < output_shape.at(0); ++gt) {
+ for (size_t tp = 0; tp < output_shape.at(1); ++tp) {
+ for (size_t c = 0; c < output_shape.at(2); ++c) {
+ for (size_t gh = 0; gh < output_shape.at(3); ++gh) {
+ for (size_t ms1 = 0; ms1 < output_shape.at(4); ++ms1) {
+ for (size_t p1 = 0; p1 < output_shape.at(5); ++p1) {
+ for (size_t gw = 0; gw < output_shape.at(6); ++gw) {
+ for (size_t ms2 = 0; ms2 < output_shape.at(7); ++ms2) {
+ for (size_t p2 = 0; p2 < output_shape.at(8); ++p2) {
+ size_t output_idx = gt;
+ output_idx = output_idx * output_shape.at(1) + tp;
+ output_idx = output_idx * output_shape.at(2) + c;
+ output_idx = output_idx * output_shape.at(3) + gh;
+ output_idx = output_idx * output_shape.at(4) + ms1;
+ output_idx = output_idx * output_shape.at(5) + p1;
+ output_idx = output_idx * output_shape.at(6) + gw;
+ output_idx = output_idx * output_shape.at(7) + ms2;
+ output_idx = output_idx * output_shape.at(8) + p2;
+
+ output_data[output_idx] = input_data[input_idx];
+ input_idx++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return reshaped_patches;
+}
+
+ov::Tensor transpose_image_patches_qwen2vl(const ov::Tensor& reshaped_patches) {
+ // Input dimensions order: [0,1,2,3,4,5,6,7,8]
+ // Output dimensions order: [0,3,6,4,7,2,1,5,8]
+ auto input_shape = reshaped_patches.get_shape();
+
+ ov::Shape output_shape = {
+ input_shape.at(0), // grid_t
+ input_shape.at(3), // grid_h / spatial_merge_size
+ input_shape.at(6), // grid_w / spatial_merge_size
+ input_shape.at(4), // spatial_merge_size
+ input_shape.at(7), // spatial_merge_size
+ input_shape.at(2), // channel
+ input_shape.at(1), // temporal_patch_size
+ input_shape.at(5), // patch_size
+ input_shape.at(8) // patch_size
+ };
+
+ ov::Tensor transposed_patches(reshaped_patches.get_element_type(), output_shape);
+
+ const float* src = reshaped_patches.data();
+ float* dst = transposed_patches.data();
+
+ size_t shape_size = input_shape.size();
+ std::vector input_strides(shape_size);
+ std::vector output_strides(shape_size);
+
+ input_strides[shape_size - 1] = 1;
+ output_strides[shape_size - 1] = 1;
+ for(int i = 7; i >= 0; i--) {
+ input_strides[i] = input_strides[i+1] * input_shape[i+1];
+ output_strides[i] = output_strides[i+1] * output_shape[i+1];
+ }
+
+ size_t total_elements = reshaped_patches.get_size();
+ for(size_t idx = 0; idx < total_elements; idx++) {
+ size_t remaining = idx;
+ std::vector input_indices(shape_size);
+ for(int i = 0; i < shape_size; i++) {
+ input_indices[i] = remaining / input_strides[i];
+ remaining %= input_strides[i];
+ }
+
+ std::vector output_indices = {
+ input_indices.at(0),
+ input_indices.at(3),
+ input_indices.at(6),
+ input_indices.at(4),
+ input_indices.at(7),
+ input_indices.at(2),
+ input_indices.at(1),
+ input_indices.at(5),
+ input_indices.at(8)
+ };
+
+ size_t dst_idx = 0;
+ for(int i = 0; i < shape_size; i++) {
+ dst_idx += output_indices[i] * output_strides[i];
+ }
+
+ dst[dst_idx] = src[idx];
+ }
+
+ return transposed_patches;
+}
}
VisionEncoder::VisionEncoder(const std::filesystem::path& model_dir, const VLMModelType model_type, const std::string& device, const ov::AnyMap device_config) :
@@ -678,8 +830,10 @@ EncodedImage VisionEncoder::encode(const ov::Tensor& image, const ProcessorConfi
return encode_llava(image, config);
} else if (model_type == VLMModelType::LLAVA_NEXT) {
return encode_llava_next(image, config);
- } else if (model_type == VLMModelType::INTERNVL_CHAT) {
+ } else if (model_type == VLMModelType::INTERNVL_CHAT) {
return encode_internvl(image, config);
+ } else if (model_type == VLMModelType::QWEN2_VL) {
+ return encode_qwen2vl(image, config);
} else {
OPENVINO_THROW("Unsupported type of VisionEncoder");
}
@@ -753,3 +907,74 @@ EncodedImage VisionEncoder::encode_internvl(const ov::Tensor& image, const Proce
return {std::move(image_features), resized_source_size};
}
+
+EncodedImage VisionEncoder::encode_qwen2vl(const ov::Tensor& image, const ProcessorConfig& config) {
+ ov::Shape image_shape = image.get_shape();
+ auto original_height = image_shape.at(1);
+ auto original_width = image_shape.at(2);
+
+ ImageSize target_image_size = smart_resize_qwen2vl(
+ original_height,
+ original_width,
+ config.patch_size * config.merge_size,
+ config.min_pixels,
+ config.max_pixels
+ );
+
+ clip_image_u8 input_image = tensor_to_clip_image_u8(image);
+ clip_image_u8 resized_image;
+ bicubic_resize(input_image, resized_image, target_image_size.width, target_image_size.height);
+
+ clip_ctx ctx;
+ std::copy(config.image_mean.begin(), config.image_mean.end(), ctx.image_mean);
+ std::copy(config.image_std.begin(), config.image_std.end(), ctx.image_std);
+ clip_image_f32 normalized_image = clip_image_preprocess(ctx, resized_image);
+
+ ov::Tensor patches = clip_image_f32_to_tensor(normalized_image);
+
+ // For single patch tile it to match temporal_patch_size
+ if (patches.get_shape().at(0) == 1) {
+ auto orig_shape = patches.get_shape();
+ ov::Tensor tiled_patches(patches.get_element_type(),
+ {config.temporal_patch_size, orig_shape.at(1), orig_shape.at(2), orig_shape.at(3)});
+
+ for (size_t i = 0; i < config.temporal_patch_size; i++) {
+ std::memcpy(
+ tiled_patches.data() + i * patches.get_byte_size() / sizeof(float),
+ patches.data(),
+ patches.get_byte_size()
+ );
+ }
+ patches = std::move(tiled_patches);
+ }
+
+ auto patches_shape = patches.get_shape();
+ size_t channel = patches_shape.at(1);
+
+ size_t grid_t = patches_shape.at(0) / config.temporal_patch_size;
+ size_t grid_h = target_image_size.height / config.patch_size;
+ size_t grid_w = target_image_size.width / config.patch_size;
+
+ ov::Tensor reshaped_patches = reshape_image_patches_qwen2vl(
+ patches, grid_t, grid_h, grid_w, channel, config.temporal_patch_size, config.patch_size, config.merge_size
+ );
+ ov::Tensor transposed_patches = transpose_image_patches_qwen2vl(reshaped_patches);
+
+ ov::Shape flattened_patches_shape{
+ grid_t * grid_h * grid_w,
+ channel * config.temporal_patch_size * config.patch_size * config.patch_size
+ };
+ ov::Tensor flattened_patches(transposed_patches.get_element_type(), flattened_patches_shape);
+ std::memcpy(flattened_patches.data(), transposed_patches.data(), transposed_patches.get_byte_size());
+
+ m_vision_encoder.set_tensor("hidden_states", flattened_patches);
+ m_vision_encoder.infer();
+
+ const ov::Tensor& infer_output = m_vision_encoder.get_output_tensor();
+ ov::Tensor image_features(infer_output.get_element_type(), infer_output.get_shape());
+ std::memcpy(image_features.data(), infer_output.data(), infer_output.get_byte_size());
+
+ ImageSize resized_source_size{grid_h, grid_w};
+
+ return {std::move(image_features), resized_source_size};
+}
diff --git a/src/cpp/src/visual_language/vision_encoder.hpp b/src/cpp/src/visual_language/vision_encoder.hpp
index d94a898353..e725c06bf4 100644
--- a/src/cpp/src/visual_language/vision_encoder.hpp
+++ b/src/cpp/src/visual_language/vision_encoder.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -158,5 +158,9 @@ class VisionEncoder {
EncodedImage encode_internvl(
const ov::Tensor& image, const ProcessorConfig& config
);
+
+ EncodedImage encode_qwen2vl(
+ const ov::Tensor& image, const ProcessorConfig& config
+ );
};
}
diff --git a/src/cpp/src/visual_language/vlm_config.cpp b/src/cpp/src/visual_language/vlm_config.cpp
index c711998128..6eab781fc0 100644
--- a/src/cpp/src/visual_language/vlm_config.cpp
+++ b/src/cpp/src/visual_language/vlm_config.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "vlm_config.hpp"
diff --git a/src/cpp/src/visual_language/vlm_config.hpp b/src/cpp/src/visual_language/vlm_config.hpp
index c126d5495e..c70c757707 100644
--- a/src/cpp/src/visual_language/vlm_config.hpp
+++ b/src/cpp/src/visual_language/vlm_config.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -55,6 +55,13 @@ class VLMConfig {
/// @brief A string token denoting end of image embeddings for InternVL2 model.
std::string image_end_token = "";
+ /// @brief A string token denoting start of vision embeddings for Qwen2VL model.
+ std::string vision_start_token = "<|vision_start|>";
+ /// @brief A placeholder for image embeddings in text for Qwen2VL model.
+ std::string image_pad_token = "<|image_pad|>";
+ /// @brief A string token denoting end of vision embeddings for Qwen2VL model.
+ std::string vision_end_token = "<|vision_end|>";
+
/// @brief Default constructor.
VLMConfig() = default;
/// @brief Construct VLMConfig from values in json_path.
diff --git a/src/cpp/src/visual_language/vlm_model_type.hpp b/src/cpp/src/visual_language/vlm_model_type.hpp
index e4b5e823b6..6f554fbf98 100644
--- a/src/cpp/src/visual_language/vlm_model_type.hpp
+++ b/src/cpp/src/visual_language/vlm_model_type.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
@@ -16,6 +16,7 @@ enum class VLMModelType {
LLAVA,
LLAVA_NEXT,
INTERNVL_CHAT,
+ QWEN2_VL,
};
inline VLMModelType to_vlm_model_type(const std::string& value) {
@@ -23,7 +24,8 @@ inline VLMModelType to_vlm_model_type(const std::string& value) {
{"minicpmv", VLMModelType::MINICPM},
{"llava", VLMModelType::LLAVA},
{"llava_next", VLMModelType::LLAVA_NEXT},
- {"internvl_chat", VLMModelType::INTERNVL_CHAT}
+ {"internvl_chat", VLMModelType::INTERNVL_CHAT},
+ {"qwen2_vl", VLMModelType::QWEN2_VL}
};
auto it = model_types_map.find(value);
diff --git a/src/cpp/src/whisper/context_tokens.cpp b/src/cpp/src/whisper/context_tokens.cpp
index 75ee442551..d39ba7cc91 100644
--- a/src/cpp/src/whisper/context_tokens.cpp
+++ b/src/cpp/src/whisper/context_tokens.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "context_tokens.hpp"
diff --git a/src/cpp/src/whisper/context_tokens.hpp b/src/cpp/src/whisper/context_tokens.hpp
index 0042ba8136..422e7124e4 100644
--- a/src/cpp/src/whisper/context_tokens.hpp
+++ b/src/cpp/src/whisper/context_tokens.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/whisper/logit_processor.cpp b/src/cpp/src/whisper/logit_processor.cpp
index d3d9552f57..92ae39bd4c 100644
--- a/src/cpp/src/whisper/logit_processor.cpp
+++ b/src/cpp/src/whisper/logit_processor.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/cpp/src/whisper/logit_processor.hpp b/src/cpp/src/whisper/logit_processor.hpp
index ee51f905b5..2dd52a7905 100644
--- a/src/cpp/src/whisper/logit_processor.hpp
+++ b/src/cpp/src/whisper/logit_processor.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/whisper/perf_metrics.cpp b/src/cpp/src/whisper/perf_metrics.cpp
index 3947ef616e..4d11acf266 100644
--- a/src/cpp/src/whisper/perf_metrics.cpp
+++ b/src/cpp/src/whisper/perf_metrics.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/whisper_pipeline.hpp"
diff --git a/src/cpp/src/whisper/streamer.cpp b/src/cpp/src/whisper/streamer.cpp
index 4cfce54442..cf84a0b9b2 100644
--- a/src/cpp/src/whisper/streamer.cpp
+++ b/src/cpp/src/whisper/streamer.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "streamer.hpp"
diff --git a/src/cpp/src/whisper/streamer.hpp b/src/cpp/src/whisper/streamer.hpp
index 26c948e16d..df81b03f20 100644
--- a/src/cpp/src/whisper/streamer.hpp
+++ b/src/cpp/src/whisper/streamer.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/whisper/timestamps.cpp b/src/cpp/src/whisper/timestamps.cpp
index 41b9fce59f..f2fadafb3b 100644
--- a/src/cpp/src/whisper/timestamps.cpp
+++ b/src/cpp/src/whisper/timestamps.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "timestamps.hpp"
diff --git a/src/cpp/src/whisper/timestamps.hpp b/src/cpp/src/whisper/timestamps.hpp
index ac43f6109a..0dcb6e6ef5 100644
--- a/src/cpp/src/whisper/timestamps.hpp
+++ b/src/cpp/src/whisper/timestamps.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/whisper/whisper.cpp b/src/cpp/src/whisper/whisper.cpp
index 3ab873609d..0f523e3bee 100644
--- a/src/cpp/src/whisper/whisper.cpp
+++ b/src/cpp/src/whisper/whisper.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "whisper.hpp"
diff --git a/src/cpp/src/whisper/whisper.hpp b/src/cpp/src/whisper/whisper.hpp
index fbdf56d171..aed6487160 100644
--- a/src/cpp/src/whisper/whisper.hpp
+++ b/src/cpp/src/whisper/whisper.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/whisper/whisper_config.cpp b/src/cpp/src/whisper/whisper_config.cpp
index ab34063184..2818430aa6 100644
--- a/src/cpp/src/whisper/whisper_config.cpp
+++ b/src/cpp/src/whisper/whisper_config.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "whisper_config.hpp"
diff --git a/src/cpp/src/whisper/whisper_config.hpp b/src/cpp/src/whisper/whisper_config.hpp
index 8e67c3b5ab..e0f23aee04 100644
--- a/src/cpp/src/whisper/whisper_config.hpp
+++ b/src/cpp/src/whisper/whisper_config.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/whisper/whisper_feature_extractor.cpp b/src/cpp/src/whisper/whisper_feature_extractor.cpp
index 04070404c0..4a2fbe5a9b 100644
--- a/src/cpp/src/whisper/whisper_feature_extractor.cpp
+++ b/src/cpp/src/whisper/whisper_feature_extractor.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#ifdef _WIN32
diff --git a/src/cpp/src/whisper/whisper_feature_extractor.hpp b/src/cpp/src/whisper/whisper_feature_extractor.hpp
index 9197cc32ea..9f01aa0320 100644
--- a/src/cpp/src/whisper/whisper_feature_extractor.hpp
+++ b/src/cpp/src/whisper/whisper_feature_extractor.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/whisper/whisper_models.hpp b/src/cpp/src/whisper/whisper_models.hpp
index 9a915e92f4..b2edfcccfe 100644
--- a/src/cpp/src/whisper/whisper_models.hpp
+++ b/src/cpp/src/whisper/whisper_models.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
diff --git a/src/cpp/src/whisper_generation_config.cpp b/src/cpp/src/whisper_generation_config.cpp
index beb663caaf..1cc79ab0e6 100644
--- a/src/cpp/src/whisper_generation_config.cpp
+++ b/src/cpp/src/whisper_generation_config.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/whisper_generation_config.hpp"
diff --git a/src/cpp/src/whisper_pipeline.cpp b/src/cpp/src/whisper_pipeline.cpp
index ffd792c889..70e3950536 100644
--- a/src/cpp/src/whisper_pipeline.cpp
+++ b/src/cpp/src/whisper_pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "openvino/genai/whisper_pipeline.hpp"
diff --git a/src/cpp/src/whisper_pipeline_static.cpp b/src/cpp/src/whisper_pipeline_static.cpp
index 91de478b1c..551774ec59 100644
--- a/src/cpp/src/whisper_pipeline_static.cpp
+++ b/src/cpp/src/whisper_pipeline_static.cpp
@@ -347,7 +347,7 @@ void add_attention_mask_input(std::shared_ptr model) {
using namespace ov::op;
class AttentionMaskInput : public ov::pass::MatcherPass {
public:
- OPENVINO_RTTI("AttentionMaskInput");
+ OPENVINO_MATCHER_PASS_RTTI("AttentionMaskInput");
AttentionMaskInput(std::shared_ptr model) {
auto range = wrap_type();
diff --git a/src/docs/BUILD.md b/src/docs/BUILD.md
index 77657620a0..4cda924fd2 100644
--- a/src/docs/BUILD.md
+++ b/src/docs/BUILD.md
@@ -191,9 +191,11 @@ The path to the openvino install directory is referred as througho
```
4. Build the wheel in the `dist` directory:
```sh
- python -m pip wheel . -w dist/ --extra-index-url https://storage.openvinotoolkit.org/simple/wheels/pre-release
+ python -m pip wheel . -w dist/ --extra-index-url https://storage.openvinotoolkit.org/simple/wheels/pre-release --extra-index-url https://storage.openvinotoolkit.org/simple/wheels/nightly
```
+> **NOTE**: You'd need to build ABI compatible OpenVINO and OpenVINO Tokenizers for Ubuntu instead of downloading them from PyPI. See [OpenVINO™ GenAI Dependencies](../README.md#openvino-genai-dependencies) for the explanation.
+
### Install OpenVINO GenAI From Source
1. Clone OpenVINO GenAI repository and init submodules:
diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt
index 1293246260..bb832d5acd 100644
--- a/src/python/CMakeLists.txt
+++ b/src/python/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
diff --git a/src/python/py_continuous_batching_pipeline.cpp b/src/python/py_continuous_batching_pipeline.cpp
index d6888c4547..6df67b3a39 100644
--- a/src/python/py_continuous_batching_pipeline.cpp
+++ b/src/python/py_continuous_batching_pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/python/py_generation_config.cpp b/src/python/py_generation_config.cpp
index a97a43fc5c..e2a6d7062c 100644
--- a/src/python/py_generation_config.cpp
+++ b/src/python/py_generation_config.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/python/py_image_generation_models.cpp b/src/python/py_image_generation_models.cpp
index 75be28233f..877977926e 100644
--- a/src/python/py_image_generation_models.cpp
+++ b/src/python/py_image_generation_models.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/python/py_image_generation_pipelines.cpp b/src/python/py_image_generation_pipelines.cpp
index c246557a97..b011aee878 100644
--- a/src/python/py_image_generation_pipelines.cpp
+++ b/src/python/py_image_generation_pipelines.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/python/py_llm_pipeline.cpp b/src/python/py_llm_pipeline.cpp
index 2d5e5e6abc..969059ee16 100644
--- a/src/python/py_llm_pipeline.cpp
+++ b/src/python/py_llm_pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/python/py_lora_adapter.cpp b/src/python/py_lora_adapter.cpp
index 7f98b67064..ddaf6e2081 100644
--- a/src/python/py_lora_adapter.cpp
+++ b/src/python/py_lora_adapter.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/python/py_openvino_genai.cpp b/src/python/py_openvino_genai.cpp
index f8e577d5c8..8b8bd831b0 100644
--- a/src/python/py_openvino_genai.cpp
+++ b/src/python/py_openvino_genai.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/python/py_perf_metrics.cpp b/src/python/py_perf_metrics.cpp
index 1d17e34905..17e71150ac 100644
--- a/src/python/py_perf_metrics.cpp
+++ b/src/python/py_perf_metrics.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/python/py_tokenizer.cpp b/src/python/py_tokenizer.cpp
index db4643a65c..0dd9f3d715 100644
--- a/src/python/py_tokenizer.cpp
+++ b/src/python/py_tokenizer.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/src/python/py_utils.cpp b/src/python/py_utils.cpp
index bad702d54d..90cce498cd 100644
--- a/src/python/py_utils.cpp
+++ b/src/python/py_utils.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "py_utils.hpp"
@@ -72,6 +72,8 @@ ov::Any py_object_to_any(const py::object& py_obj, std::string property_name) {
std::set any_map_properties = {
"GENERATE_CONFIG",
"PREFILL_CONFIG",
+ "++GENERATE_CONFIG",
+ "++PREFILL_CONFIG"
};
py::object float_32_type = py::module_::import("numpy").attr("float32");
diff --git a/src/python/py_utils.hpp b/src/python/py_utils.hpp
index 9d78ab0930..c3dbdf6aee 100644
--- a/src/python/py_utils.hpp
+++ b/src/python/py_utils.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#define PYBIND11_DETAILED_ERROR_MESSAGES
diff --git a/src/python/py_vlm_pipeline.cpp b/src/python/py_vlm_pipeline.cpp
index e076d87f11..f070c32629 100644
--- a/src/python/py_vlm_pipeline.cpp
+++ b/src/python/py_vlm_pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
diff --git a/src/python/py_whisper_pipeline.cpp b/src/python/py_whisper_pipeline.cpp
index d290612ed6..55728409e8 100644
--- a/src/python/py_whisper_pipeline.cpp
+++ b/src/python/py_whisper_pipeline.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt
index 5880010841..9e557aeabc 100644
--- a/tests/cpp/CMakeLists.txt
+++ b/tests/cpp/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
diff --git a/tests/cpp/block_allocator.cpp b/tests/cpp/block_allocator.cpp
index a89233b2a9..982d38a0eb 100644
--- a/tests/cpp/block_allocator.cpp
+++ b/tests/cpp/block_allocator.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2024 Intel Corporation
+// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/tests/cpp/block_hash_store.cpp b/tests/cpp/block_hash_store.cpp
index 6827a332b8..61c706cfb6 100644
--- a/tests/cpp/block_hash_store.cpp
+++ b/tests/cpp/block_hash_store.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2024 Intel Corporation
+// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
diff --git a/tests/cpp/block_manager.cpp b/tests/cpp/block_manager.cpp
index 670a0dffe7..9501eaefb5 100644
--- a/tests/cpp/block_manager.cpp
+++ b/tests/cpp/block_manager.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2024 Intel Corporation
+// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
diff --git a/tests/cpp/cache_manager.cpp b/tests/cpp/cache_manager.cpp
index 095cc39f09..7d855ded12 100644
--- a/tests/cpp/cache_manager.cpp
+++ b/tests/cpp/cache_manager.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2024 Intel Corporation
+// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
diff --git a/tests/cpp/device_config.cpp b/tests/cpp/device_config.cpp
index 973648f637..93e06f02e7 100644
--- a/tests/cpp/device_config.cpp
+++ b/tests/cpp/device_config.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2024 Intel Corporation
+// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
diff --git a/tests/cpp/scheduler.cpp b/tests/cpp/scheduler.cpp
index 23594adf50..ecd53fa665 100644
--- a/tests/cpp/scheduler.cpp
+++ b/tests/cpp/scheduler.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2024 Intel Corporation
+// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
diff --git a/tests/cpp/utils.cpp b/tests/cpp/utils.cpp
index d00edae6fb..14b110b993 100644
--- a/tests/cpp/utils.cpp
+++ b/tests/cpp/utils.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2024 Intel Corporation
+// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
diff --git a/tests/python_tests/common.py b/tests/python_tests/common.py
index 2fca58a959..cbed01e20f 100644
--- a/tests/python_tests/common.py
+++ b/tests/python_tests/common.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
@@ -7,10 +7,10 @@
from optimum.intel import OVModelForCausalLM
from pathlib import Path
-from openvino_genai import ContinuousBatchingPipeline, LLMPipeline, SchedulerConfig, GenerationResult, GenerationConfig, DecodedResults, StopCriteria
+from openvino_genai import ContinuousBatchingPipeline, LLMPipeline, SchedulerConfig, GenerationResult, GenerationConfig, DecodedResults, StopCriteria, StreamerBase
from transformers import AutoTokenizer, AutoModelForCausalLM
from transformers import GenerationConfig as HFGenerationConfig
-from typing import List, Tuple
+from typing import List, Tuple, Callable
TESTS_ROOT = Path(__file__).parent
@@ -325,19 +325,50 @@ def get_default_properties():
}
+class StreamerWithResults:
+ # Return a streamer which accumulates results in order to compare with results returned from generate.
+ results: List[str] = []
+ def __init__(self):
+ self.results = []
+
+ def accumulate(self, subword) -> bool:
+ self.results.append(subword)
+ return False
+
+ def get_results(self) -> List[GenerationResult]:
+ streaming_result = GenerationResult()
+ streaming_result.m_generation_ids = [''.join(self.results)]
+ return [streaming_result]
+
+ def reset(self):
+ self.results = []
+
+
+
def run_llm_pipeline(
models_path : Path,
prompts: List[str],
generation_config : GenerationConfig,
- use_cb : bool = False
+ use_cb : bool = False,
+ streamer: StreamerWithResults | Callable | StreamerBase = None
) -> List[GenerationResult]:
properties = get_default_properties()
if use_cb:
properties['scheduler_config'] = SchedulerConfig()
-
ov_pipe = LLMPipeline(models_path, device='CPU', **properties)
-
- generate_outputs : DecodedResults = ov_pipe.generate(inputs=prompts, generation_config=generation_config)
+
+ if streamer is None and not (generation_config.is_beam_search() or generation_config.num_return_sequences > 1) and len(prompts) == 1:
+ # We can use streamer only if we have a single prompt and not beam search.
+ streamer = StreamerWithResults()
+ if isinstance(streamer, StreamerWithResults):
+ # Clear the accumulated strings to avoid side effects
+ streamer.reset()
+
+ generate_outputs : DecodedResults = ov_pipe.generate(
+ inputs=prompts,
+ generation_config=generation_config,
+ streamer=streamer.accumulate if isinstance(streamer, StreamerWithResults) else streamer
+ )
index = 0
generation_results = []
@@ -355,6 +386,9 @@ def run_llm_pipeline(
del ov_pipe
shutil.rmtree(models_path)
+
+ if isinstance(streamer, StreamerWithResults):
+ compare_generation_results(prompts, generation_results, streamer.get_results(), generation_config)
return generation_results
@@ -410,9 +444,14 @@ def convert_models(opt_model : OVModelForCausalLM, hf_tokenizer : AutoTokenizer,
tokenizer, detokenizer = convert_tokenizer(hf_tokenizer, with_detokenizer=True)
serialize(tokenizer, models_path / "openvino_tokenizer.xml")
serialize(detokenizer, models_path / "openvino_detokenizer.xml")
+
-
-def run_llm_pipeline_with_ref(model_id: str, prompts: List[str], generation_config: GenerationConfig | dict, tmp_path: Path, use_cb : bool = False):
+def run_llm_pipeline_with_ref(model_id: str,
+ prompts: List[str],
+ generation_config: GenerationConfig | dict,
+ tmp_path: Path,
+ use_cb : bool = False,
+ streamer: StreamerWithResults | Callable | StreamerBase = None):
models_path : Path = tmp_path / model_id
opt_model, hf_tokenizer = get_hugging_face_models(model_id)
@@ -421,7 +460,7 @@ def run_llm_pipeline_with_ref(model_id: str, prompts: List[str], generation_conf
convert_models(opt_model, hf_tokenizer, models_path)
- ov_results = run_llm_pipeline(models_path, prompts, generation_config, use_cb)
+ ov_results = run_llm_pipeline(models_path, prompts, generation_config, use_cb, streamer=streamer.accumulate if isinstance(streamer, StreamerWithResults) else streamer)
hf_results = run_hugging_face(opt_model, hf_tokenizer, prompts, generation_config)
compare_generation_results(prompts, hf_results, ov_results, generation_config)
diff --git a/tests/python_tests/requirements.txt b/tests/python_tests/requirements.txt
index 78cacd61ae..8d0f6d4e30 100644
--- a/tests/python_tests/requirements.txt
+++ b/tests/python_tests/requirements.txt
@@ -1,5 +1,5 @@
--extra-index-url https://download.pytorch.org/whl/cpu
-diffusers==0.32.1
+diffusers==0.32.2
optimum-intel @ git+https://github.com/eaidova/optimum-intel@ea/stateful_seq2seq
numpy<2.0.0; platform_system == "Darwin" and platform_machine == "x86_64"
onnx==1.17.0
diff --git a/tests/python_tests/test_continuous_batching.py b/tests/python_tests/test_continuous_batching.py
index d7ce0b1ece..e8081f30e6 100644
--- a/tests/python_tests/test_continuous_batching.py
+++ b/tests/python_tests/test_continuous_batching.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
@@ -117,7 +117,7 @@ def test_cb_streamer_vs_return_vs_stateful(prompt):
@pytest.mark.parametrize("model_descr", get_chat_models_list())
@pytest.mark.precommit
def test_chat_scenario_vs_stateful(model_descr, generation_config_kwargs: Dict):
- model_id, models_path, hf_tokenizer, opt_model, ov_pipe = read_model((model_descr[0], model_descr[1] / '_test_chat'))
+ model_id, models_path, hf_tokenizer, opt_model, ov_pipe = read_model((model_descr[0], model_descr[1]))
cb_pipe = get_continuous_batching(models_path)
ov_pipe.start_chat()
diff --git a/tests/python_tests/test_generation_config.py b/tests/python_tests/test_generation_config.py
index 0a42685b05..1b3c44b69e 100644
--- a/tests/python_tests/test_generation_config.py
+++ b/tests/python_tests/test_generation_config.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from openvino_genai import GenerationConfig
diff --git a/tests/python_tests/test_kv_cache_eviction.py b/tests/python_tests/test_kv_cache_eviction.py
index 428047ea28..43fd82412f 100644
--- a/tests/python_tests/test_kv_cache_eviction.py
+++ b/tests/python_tests/test_kv_cache_eviction.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from dataclasses import dataclass
from pathlib import Path
diff --git a/tests/python_tests/test_llm_pipeline.py b/tests/python_tests/test_llm_pipeline.py
index 031c42a1dc..8968f2a083 100644
--- a/tests/python_tests/test_llm_pipeline.py
+++ b/tests/python_tests/test_llm_pipeline.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import openvino_genai as ov_genai
@@ -129,7 +129,7 @@ def test_chat_scenario(model_descr, generation_config_kwargs: Dict):
chat_history_hf = []
chat_history_ov = []
- model_id, path, tokenizer, opt_model, ov_pipe = read_model((model_descr[0], model_descr[1] / '_test_chat'))
+ model_id, path, tokenizer, opt_model, ov_pipe = read_model((model_descr[0], model_descr[1]))
ov_generation_config = GenerationConfig(**generation_config_kwargs)
hf_generation_config = convert_to_hf(opt_model.generation_config, ov_generation_config)
@@ -363,7 +363,7 @@ def test_unicode_pybind_decoding_one_string_streamer():
ov_pipe = read_model((model_id, path))[4]
res_str = []
ov_pipe.generate(",", max_new_tokens=4, streamer=lambda x: res_str.append(x))
- assert '�' == res_str[-1]
+ assert '�' == ''.join(res_str)[-1]
#
# Perf metrics
diff --git a/tests/python_tests/test_llm_pipeline_static.py b/tests/python_tests/test_llm_pipeline_static.py
index d2d3673356..ae5c475fd9 100644
--- a/tests/python_tests/test_llm_pipeline_static.py
+++ b/tests/python_tests/test_llm_pipeline_static.py
@@ -17,7 +17,6 @@
from common import \
get_greedy, \
get_greedy_with_penalties, \
- get_multinomial_temperature, \
get_multinomial_all_parameters, \
get_multinomial_temperature_and_presence_penalty, \
get_beam_search
@@ -34,7 +33,7 @@
'NPUW_ONLINE_PIPELINE': 'NONE',
'PREFILL_CONFIG': { },
'GENERATE_CONFIG': { }
- }
+ } | get_default_properties()
def generate_chat_history(model_path, device, pipeline_config, questions):
@@ -56,7 +55,7 @@ def test_generation_compare_with_stateful(generation_config):
prompt = 'What is OpenVINO?'
model_path = read_model(get_models_list()[0])[1]
- stateful_pipe = ov_genai.LLMPipeline(model_path, "CPU")
+ stateful_pipe = ov_genai.LLMPipeline(model_path, "CPU", **get_default_properties())
ref_out = stateful_pipe.generate(prompt, generation_config)
static_pipe = ov_genai.LLMPipeline(model_path, "NPU", **common_config)
diff --git a/tests/python_tests/test_sampling.py b/tests/python_tests/test_sampling.py
index 004d4f9d9d..7a3aced29a 100644
--- a/tests/python_tests/test_sampling.py
+++ b/tests/python_tests/test_sampling.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import sys
@@ -9,7 +9,7 @@
from openvino_genai import GenerationConfig, StopCriteria
from typing import List, TypedDict
-from common import get_hugging_face_models, convert_models, run_llm_pipeline_with_ref, run_llm_pipeline
+from common import get_hugging_face_models, convert_models, run_llm_pipeline_with_ref, run_llm_pipeline, compare_generation_results, StreamerWithResults
@pytest.mark.precommit
@@ -58,13 +58,27 @@ def test_stop_strings(tmp_path, generation_config):
@pytest.mark.precommit
@pytest.mark.parametrize("generation_config",
[dict(max_new_tokens=30),
- dict(max_new_tokens=30, repetition_penalty=2.0),],
- ids=["basic",
- "repetition_penalty",])
-def test_greedy(tmp_path, generation_config):
- prompts = [ "What is OpenVINO?" ]
+ dict(max_new_tokens=30, repetition_penalty=2.0),
+ dict(max_new_tokens=300)],
+ ids=["basic", "repetition_penalty", "long_max_new_tokens"])
+@pytest.mark.parametrize("prompt", [
+ 'What is OpenVINO?',
+ 'table is made of',
+ 'The Sun is yellow because',
+ '你好! 你好嗎?',
+ 'I have an interview about product speccing with the company Weekend Health. Give me an example of a question they might ask with regards about a new feature'
+])
+@pytest.mark.parametrize("use_cb", [True, False])
+def test_greedy(tmp_path, generation_config, prompt, use_cb):
model_id : str = "katuni4ka/tiny-random-phi3"
- run_llm_pipeline_with_ref(model_id, prompts, generation_config, tmp_path)
+ if sys.platform.startswith('win') and prompt.startswith('你'):
+ pytest.skip("For unknown reason this prompt fails on Win")
+
+ run_llm_pipeline_with_ref(model_id=model_id,
+ prompts=[prompt],
+ generation_config=generation_config,
+ tmp_path=tmp_path,
+ use_cb=use_cb)
@pytest.mark.precommit
@@ -319,13 +333,14 @@ def test_multinomial_sampling_against_reference(tmp_path, test_struct: RandomSam
prompts = test_struct.prompts
generation_config.rng_seed = 0
generation_configs = generation_config
+
model_id : str = "facebook/opt-125m"
model, hf_tokenizer = get_hugging_face_models(model_id)
models_path : Path = tmp_path / model_id
convert_models(model, hf_tokenizer, models_path)
- # run multinomial without comparison with reference
+ # Run multinomial without comparison with HF reference.
_ = run_llm_pipeline(models_path, prompts, generation_configs)
# Reference comparison is not performed as sampling results are non-deterministic.
diff --git a/tests/python_tests/test_tokenizer.py b/tests/python_tests/test_tokenizer.py
index 8129298763..d2faa227d5 100644
--- a/tests/python_tests/test_tokenizer.py
+++ b/tests/python_tests/test_tokenizer.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
@@ -181,12 +181,18 @@ def test_apply_chat_template(model_tmp_path, chat_config: Tuple[str, Dict]):
print(f'ov_genai out: {ov_full_history_str}')
assert ov_full_history_str == hf_full_history_str
+ # Test throwing exception for empty rendered chat template
+ # Example: Qwen2-VL chat template
+ chat_template_for_empty_output = "{% if messages is string %}{{ messages }}{% else %}{% for content in messages %}{% if content['type'] == 'image' or 'image' in content or 'image_url' in content %}<|vision_start|><|image_pad|><|vision_end|>{% elif content['type'] == 'video' or 'video' in content %}<|vision_start|><|video_pad|><|vision_end|>{% elif 'text' in content %}{{ content['text'] }}{% endif %}{% endfor %}{% endif %}"
+ with pytest.raises(Exception):
+ ov_tokenizer.apply_chat_template(conversation, chat_template=chat_template_for_empty_output)
+
@pytest.mark.precommit
@pytest.mark.nightly
def test_set_chat_template():
model_descr = get_chat_models_list()[0]
- model_id, path, hf_tokenizer, opt_model, ov_pipe = read_model((model_descr[0], model_descr[1] / '_test_chat'))
+ model_id, path, hf_tokenizer, opt_model, ov_pipe = read_model((model_descr[0], model_descr[1]))
prompt = "how are you?"
dummy_conversation = [
@@ -217,24 +223,36 @@ def test_set_chat_template():
]
@pytest.mark.precommit
@pytest.mark.nightly
-@pytest.mark.parametrize("add_special_tokens", [True, False])
-@pytest.mark.parametrize("skip_special_tokens", [True, False])
@pytest.mark.parametrize("prompt", prompts)
-def test_encode_decode_with_special_tokens_option(add_special_tokens, skip_special_tokens, prompt):
+def test_encode_decode_with_special_tokens_option(prompt):
import numpy as np
- model_descr = get_chat_models_list()[0]
- model_id, path, hf_tokenizer, model_opt, ov_pipe = read_model((model_descr[0], model_descr[1] / '_test_chat'))
+ model_descr = get_models_list()[0]
+ model_id, path, hf_tokenizer, model_opt, ov_pipe = read_model((model_descr[0], model_descr[1]))
ov_tokenzier = ov_pipe.get_tokenizer()
# Calling encode with 'add_special_tokens' will set state flag.
- ov_res = ov_tokenzier.encode(prompt, add_special_tokens=add_special_tokens).input_ids.data
- hf_res = hf_tokenizer(prompt, return_tensors="np", add_special_tokens=add_special_tokens)["input_ids"]
- assert np.all(ov_res == hf_res)
+ ov_res_add_spec = ov_tokenzier.encode(prompt, add_special_tokens=True).input_ids.data
+ ov_res_no_spec = ov_tokenzier.encode(prompt, add_special_tokens=False).input_ids.data
+ hf_res_add_spec = hf_tokenizer(prompt, return_tensors="np", add_special_tokens=True)["input_ids"]
+ hf_res_no_spec = hf_tokenizer(prompt, return_tensors="np", add_special_tokens=False)["input_ids"]
+ assert np.all(ov_res_add_spec == hf_res_add_spec)
+ assert np.all(ov_res_no_spec == hf_res_no_spec)
+
+ # Check that add_special_tokens flag indeed made any difference
+ assert ov_res_add_spec.size != ov_res_no_spec.size
+ assert hf_res_add_spec.size != hf_res_no_spec.size
# Decode with 'skip_special_tokens'
- decoded_genai = ov_tokenzier.decode(ov_res, skip_special_tokens=skip_special_tokens)[0]
- decoded_hf = hf_tokenizer.decode(hf_res[0], skip_special_tokens=skip_special_tokens)
- assert decoded_genai == decoded_hf
+ decoded_genai_skip_spec = ov_tokenzier.decode(hf_res_add_spec, skip_special_tokens=True)[0]
+ decoded_genai_no_skip = ov_tokenzier.decode(hf_res_add_spec, skip_special_tokens=False)[0]
+ decoded_hf_skip_spec = hf_tokenizer.decode(hf_res_add_spec[0], skip_special_tokens=True)
+ decoded_hf_no_skip = hf_tokenizer.decode(hf_res_add_spec[0], skip_special_tokens=False)
+ assert decoded_genai_skip_spec == decoded_hf_skip_spec
+ assert decoded_genai_no_skip == decoded_hf_no_skip
+
+ # Check that skip_special_tokens indeed made any difference
+ assert decoded_genai_skip_spec != decoded_genai_no_skip
+ assert decoded_hf_skip_spec != decoded_hf_no_skip
@pytest.mark.precommit
diff --git a/tests/python_tests/test_vlm_pipeline.py b/tests/python_tests/test_vlm_pipeline.py
index e6f897bcef..b413b6cf1d 100644
--- a/tests/python_tests/test_vlm_pipeline.py
+++ b/tests/python_tests/test_vlm_pipeline.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import openvino_tokenizers
@@ -46,6 +46,8 @@ def get_ov_model(cache):
@pytest.mark.nightly
def test_vlm_pipeline(cache):
def streamer(word: str) -> bool:
+ nonlocal result_from_streamer
+ result_from_streamer.append(word)
return False
models_path = get_ov_model(cache)
@@ -59,10 +61,14 @@ def streamer(word: str) -> bool:
ov_pipe = VLMPipeline(models_path, "CPU")
ov_pipe.start_chat()
- ov_pipe.generate(prompts[0], images=images, generation_config=generation_config, streamer=streamer)
+ result_from_streamer = []
+ res = ov_pipe.generate(prompts[0], images=images, generation_config=generation_config, streamer=streamer)
+ assert res.texts[0] == ''.join(result_from_streamer)
for prompt in prompts[1:]:
- ov_pipe.generate(prompt, generation_config=generation_config, streamer=streamer)
+ result_from_streamer = []
+ res = ov_pipe.generate(prompt, generation_config=generation_config, streamer=streamer)
+ assert res.texts[0] == ''.join(result_from_streamer)
ov_pipe.finish_chat()
diff --git a/tests/python_tests/test_whisper_pipeline.py b/tests/python_tests/test_whisper_pipeline.py
index 06d5e56b3c..4fe239b358 100644
--- a/tests/python_tests/test_whisper_pipeline.py
+++ b/tests/python_tests/test_whisper_pipeline.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import openvino_genai as ov_genai
diff --git a/thirdparty/openvino_tokenizers b/thirdparty/openvino_tokenizers
index d5f0abf827..09c7005e0d 160000
--- a/thirdparty/openvino_tokenizers
+++ b/thirdparty/openvino_tokenizers
@@ -1 +1 @@
-Subproject commit d5f0abf8271f3cd8fc98d747b3e569fbeacca532
+Subproject commit 09c7005e0da46a50cc86b0e6e4ac9b8663a7af70
diff --git a/tools/cacheviz/__init__.py b/tools/cacheviz/__init__.py
index 88b5a71df7..b755d885d3 100644
--- a/tools/cacheviz/__init__.py
+++ b/tools/cacheviz/__init__.py
@@ -1,3 +1,3 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
diff --git a/tools/cacheviz/cacheviz.py b/tools/cacheviz/cacheviz.py
index b1ccf55098..841a5eeb65 100644
--- a/tools/cacheviz/cacheviz.py
+++ b/tools/cacheviz/cacheviz.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
"""
diff --git a/tools/continuous_batching/CMakeLists.txt b/tools/continuous_batching/CMakeLists.txt
index 284915e995..5aae9983a4 100644
--- a/tools/continuous_batching/CMakeLists.txt
+++ b/tools/continuous_batching/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2018-2024 Intel Corporation
+# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
diff --git a/tools/continuous_batching/accuracy/continuous_batching_accuracy.cpp b/tools/continuous_batching/accuracy/continuous_batching_accuracy.cpp
index 8139193779..d644ba9418 100644
--- a/tools/continuous_batching/accuracy/continuous_batching_accuracy.cpp
+++ b/tools/continuous_batching/accuracy/continuous_batching_accuracy.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/tools/continuous_batching/accuracy/continuous_batching_speculative_decoding.cpp b/tools/continuous_batching/accuracy/continuous_batching_speculative_decoding.cpp
index 7112030432..eeb3c0f070 100644
--- a/tools/continuous_batching/accuracy/continuous_batching_speculative_decoding.cpp
+++ b/tools/continuous_batching/accuracy/continuous_batching_speculative_decoding.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/tools/continuous_batching/benchmark/continuous_batching_benchmark.cpp b/tools/continuous_batching/benchmark/continuous_batching_benchmark.cpp
index e0c50cda02..d7cad80fd0 100644
--- a/tools/continuous_batching/benchmark/continuous_batching_benchmark.cpp
+++ b/tools/continuous_batching/benchmark/continuous_batching_benchmark.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2023-2024 Intel Corporation
+// Copyright (C) 2023-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include
diff --git a/tools/llm_bench/benchmark.py b/tools/llm_bench/benchmark.py
index 39b6306e7f..b9e038c12e 100644
--- a/tools/llm_bench/benchmark.py
+++ b/tools/llm_bench/benchmark.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import sys
@@ -147,9 +147,9 @@ def get_argprser():
parser.add_argument("--draft_device", required=False, default=None, help="Inference device for Speculative decoding of draft model")
parser.add_argument("--draft_cb_config", required=False, default=None,
help="Path to file with Continuous Batching Scheduler settings or dict for Speculative decoding of draft model")
- parser.add_argument("--num_assistant_tokens", required=False, default=None, help="Config option num_assistant_tokens for Speculative decoding")
+ parser.add_argument("--num_assistant_tokens", required=False, default=None, help="Config option num_assistant_tokens for Speculative decoding", type=int)
parser.add_argument("--assistant_confidence_threshold", required=False, default=None,
- help="Config option assistant_confidence_threshold for Speculative decoding")
+ help="Config option assistant_confidence_threshold for Speculative decoding", type=float)
parser.add_argument(
'--end_token_stopping',
action='store_true',
diff --git a/tools/llm_bench/convert.py b/tools/llm_bench/convert.py
index 49cea02c11..aa9ab504de 100644
--- a/tools/llm_bench/convert.py
+++ b/tools/llm_bench/convert.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import sys
import gc
diff --git a/tools/llm_bench/llm_bench_utils/config_class.py b/tools/llm_bench/llm_bench_utils/config_class.py
index 9c149c98b6..76b56fb4c5 100644
--- a/tools/llm_bench/llm_bench_utils/config_class.py
+++ b/tools/llm_bench/llm_bench_utils/config_class.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from transformers import AutoTokenizer
from transformers import AutoModelForCausalLM, T5ForConditionalGeneration, BlenderbotForConditionalGeneration, AutoModel
diff --git a/tools/llm_bench/llm_bench_utils/conversion_utils/better_transformer_patch.py b/tools/llm_bench/llm_bench_utils/conversion_utils/better_transformer_patch.py
index 4def9cfa0a..7f77576487 100644
--- a/tools/llm_bench/llm_bench_utils/conversion_utils/better_transformer_patch.py
+++ b/tools/llm_bench/llm_bench_utils/conversion_utils/better_transformer_patch.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import math
diff --git a/tools/llm_bench/llm_bench_utils/conversion_utils/convert_patch.py b/tools/llm_bench/llm_bench_utils/conversion_utils/convert_patch.py
index 8edf785ad6..df5d333e04 100644
--- a/tools/llm_bench/llm_bench_utils/conversion_utils/convert_patch.py
+++ b/tools/llm_bench/llm_bench_utils/conversion_utils/convert_patch.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import torch
diff --git a/tools/llm_bench/llm_bench_utils/conversion_utils/export_configs.py b/tools/llm_bench/llm_bench_utils/conversion_utils/export_configs.py
index cf465b8f53..ba17308a42 100644
--- a/tools/llm_bench/llm_bench_utils/conversion_utils/export_configs.py
+++ b/tools/llm_bench/llm_bench_utils/conversion_utils/export_configs.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from optimum.exporters.onnx.config import TextDecoderOnnxConfig, TextDecoderWithPositionIdsOnnxConfig
from optimum.exporters.tasks import TasksManager
diff --git a/tools/llm_bench/llm_bench_utils/conversion_utils/helpers.py b/tools/llm_bench/llm_bench_utils/conversion_utils/helpers.py
index 5c6e05588e..606d6557dc 100644
--- a/tools/llm_bench/llm_bench_utils/conversion_utils/helpers.py
+++ b/tools/llm_bench/llm_bench_utils/conversion_utils/helpers.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import copy
import json
diff --git a/tools/llm_bench/llm_bench_utils/gen_output_data.py b/tools/llm_bench/llm_bench_utils/gen_output_data.py
index b65e7b5c8c..594903912d 100644
--- a/tools/llm_bench/llm_bench_utils/gen_output_data.py
+++ b/tools/llm_bench/llm_bench_utils/gen_output_data.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
diff --git a/tools/llm_bench/llm_bench_utils/hook_beam_search.py b/tools/llm_bench/llm_bench_utils/hook_beam_search.py
index d933acc3a5..49f9db8236 100644
--- a/tools/llm_bench/llm_bench_utils/hook_beam_search.py
+++ b/tools/llm_bench/llm_bench_utils/hook_beam_search.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# flake8: noqa
import time
diff --git a/tools/llm_bench/llm_bench_utils/hook_common.py b/tools/llm_bench/llm_bench_utils/hook_common.py
index c805680cee..3b0d623737 100644
--- a/tools/llm_bench/llm_bench_utils/hook_common.py
+++ b/tools/llm_bench/llm_bench_utils/hook_common.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# flake8: noqa
import logging as log
diff --git a/tools/llm_bench/llm_bench_utils/hook_greedy_search.py b/tools/llm_bench/llm_bench_utils/hook_greedy_search.py
index 9039a99e69..86a0eec4ad 100644
--- a/tools/llm_bench/llm_bench_utils/hook_greedy_search.py
+++ b/tools/llm_bench/llm_bench_utils/hook_greedy_search.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# flake8: noqa
import time
diff --git a/tools/llm_bench/llm_bench_utils/hook_sample.py b/tools/llm_bench/llm_bench_utils/hook_sample.py
index 22111c1a3f..a1e970bf4a 100644
--- a/tools/llm_bench/llm_bench_utils/hook_sample.py
+++ b/tools/llm_bench/llm_bench_utils/hook_sample.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# flake8: noqa
import time
diff --git a/tools/llm_bench/llm_bench_utils/hook_sample_v43.py b/tools/llm_bench/llm_bench_utils/hook_sample_v43.py
index 7dce578dac..94d0aa8370 100644
--- a/tools/llm_bench/llm_bench_utils/hook_sample_v43.py
+++ b/tools/llm_bench/llm_bench_utils/hook_sample_v43.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# flake8: noqa
import time
diff --git a/tools/llm_bench/llm_bench_utils/hook_sample_v45.py b/tools/llm_bench/llm_bench_utils/hook_sample_v45.py
index 1644c63a4f..2a43717e9b 100644
--- a/tools/llm_bench/llm_bench_utils/hook_sample_v45.py
+++ b/tools/llm_bench/llm_bench_utils/hook_sample_v45.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# flake8: noqa
import time
diff --git a/tools/llm_bench/llm_bench_utils/memory_profile.py b/tools/llm_bench/llm_bench_utils/memory_profile.py
index 25bf33c938..34604f8533 100644
--- a/tools/llm_bench/llm_bench_utils/memory_profile.py
+++ b/tools/llm_bench/llm_bench_utils/memory_profile.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from threading import Event, Thread
import psutil
diff --git a/tools/llm_bench/llm_bench_utils/metrics_print.py b/tools/llm_bench/llm_bench_utils/metrics_print.py
index c1446b8bfc..7a5cf21fa6 100644
--- a/tools/llm_bench/llm_bench_utils/metrics_print.py
+++ b/tools/llm_bench/llm_bench_utils/metrics_print.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import logging as log
diff --git a/tools/llm_bench/llm_bench_utils/model_utils.py b/tools/llm_bench/llm_bench_utils/model_utils.py
index d51bc8edc6..ae61cf96dd 100644
--- a/tools/llm_bench/llm_bench_utils/model_utils.py
+++ b/tools/llm_bench/llm_bench_utils/model_utils.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import argparse
import os
diff --git a/tools/llm_bench/llm_bench_utils/output_csv.py b/tools/llm_bench/llm_bench_utils/output_csv.py
index 42d75996fd..ea1402f82f 100644
--- a/tools/llm_bench/llm_bench_utils/output_csv.py
+++ b/tools/llm_bench/llm_bench_utils/output_csv.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import csv
import numpy as np
diff --git a/tools/llm_bench/llm_bench_utils/output_file.py b/tools/llm_bench/llm_bench_utils/output_file.py
index 8efbb430a7..06fa46dbd6 100644
--- a/tools/llm_bench/llm_bench_utils/output_file.py
+++ b/tools/llm_bench/llm_bench_utils/output_file.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
diff --git a/tools/llm_bench/llm_bench_utils/ov_model_classes.py b/tools/llm_bench/llm_bench_utils/ov_model_classes.py
index 0ade0f1299..17cfab4e02 100644
--- a/tools/llm_bench/llm_bench_utils/ov_model_classes.py
+++ b/tools/llm_bench/llm_bench_utils/ov_model_classes.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# flake8: noqa
import time
diff --git a/tools/llm_bench/llm_bench_utils/ov_utils.py b/tools/llm_bench/llm_bench_utils/ov_utils.py
index c45190e87a..606a39cecf 100644
--- a/tools/llm_bench/llm_bench_utils/ov_utils.py
+++ b/tools/llm_bench/llm_bench_utils/ov_utils.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from pathlib import Path
from transformers import AutoConfig, AutoProcessor, AutoTokenizer
@@ -243,9 +243,13 @@ def create_genai_text_gen_model(model_path, device, ov_config, **kwargs):
draft_model_path = kwargs.get("draft_model", '')
cb = kwargs.get("use_cb", False)
- if cb or draft_model_path:
+ cb_config = kwargs.get("cb_config")
+ use_streamer_metrics = False
+ if cb or cb_config is not None or draft_model_path:
log.info("Continuous Batching mode activated")
- ov_config["scheduler_config"] = get_scheduler_config_genai(kwargs.get("cb_config"))
+ ov_config["scheduler_config"] = get_scheduler_config_genai(cb_config)
+
+ use_streamer_metrics = not openvino_genai.get_version().startswith("2025.") or draft_model_path
if draft_model_path:
if not Path(draft_model_path).exists():
@@ -292,7 +296,7 @@ def get_tokens(self):
def get_time_list(self):
return self.token_generation_time
- streamer = TokenStreamer(llm_pipe.get_tokenizer()) if cb or draft_model_path else None
+ streamer = TokenStreamer(llm_pipe.get_tokenizer()) if use_streamer_metrics else None
return llm_pipe, tokenizer, end - start, streamer, True
diff --git a/tools/llm_bench/llm_bench_utils/parse_json_data.py b/tools/llm_bench/llm_bench_utils/parse_json_data.py
index 28fbd298cd..37f71d2075 100644
--- a/tools/llm_bench/llm_bench_utils/parse_json_data.py
+++ b/tools/llm_bench/llm_bench_utils/parse_json_data.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
diff --git a/tools/llm_bench/llm_bench_utils/pt_utils.py b/tools/llm_bench/llm_bench_utils/pt_utils.py
index 877c135a3c..a22dec9578 100644
--- a/tools/llm_bench/llm_bench_utils/pt_utils.py
+++ b/tools/llm_bench/llm_bench_utils/pt_utils.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from pathlib import Path
import torch
diff --git a/tools/llm_bench/task/image_generation.py b/tools/llm_bench/task/image_generation.py
index 02229a5284..f2fc518636 100644
--- a/tools/llm_bench/task/image_generation.py
+++ b/tools/llm_bench/task/image_generation.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import time
diff --git a/tools/llm_bench/task/speech_to_text_generation.py b/tools/llm_bench/task/speech_to_text_generation.py
index 15a47a8b6a..cb34a81a2f 100644
--- a/tools/llm_bench/task/speech_to_text_generation.py
+++ b/tools/llm_bench/task/speech_to_text_generation.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import time
diff --git a/tools/llm_bench/task/super_resolution_generation.py b/tools/llm_bench/task/super_resolution_generation.py
index afc41fb627..c2f3cff6e4 100644
--- a/tools/llm_bench/task/super_resolution_generation.py
+++ b/tools/llm_bench/task/super_resolution_generation.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import time
diff --git a/tools/llm_bench/task/text_generation.py b/tools/llm_bench/task/text_generation.py
index c768d427e7..de798f158f 100644
--- a/tools/llm_bench/task/text_generation.py
+++ b/tools/llm_bench/task/text_generation.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import time
@@ -181,14 +181,6 @@ def run_text_generation(input_text, num, model, tokenizer, args, iter_data_list,
log.warning(f"[{num}] Prompt[{prompt_index}]'s md5 {result_md5_list} "
f"is different from md5 of the {num - 1} iteration {prev_md5}")
metrics_print.print_generated(num, warm_up=(num == 0), generated=generated_text[0], prompt_idx=prompt_index)
- if not args.get("use_cb", False):
- if num == 1:
- # if the device is CPU, throw exception
- if args['devices'].lower().startswith('cpu') is True:
- assert (result_md5_list == prev_md5)
- else:
- # throw exception
- assert (result_md5_list == prev_md5)
else:
metrics_print.print_generated(num, warm_up=(num == 0), generated=generated_text[0], prompt_idx=prompt_index)
if bench_hook is not None:
@@ -231,10 +223,10 @@ def run_text_generation_genai(input_text, num, model, tokenizer, args, iter_data
if args.get('draft_model', ''):
config_info = "Speculative decoding config: "
if args.get('num_assistant_tokens', None):
- gen_config.num_assistant_tokens = args['num_assistant_tokens']
+ gen_config.num_assistant_tokens = int(args['num_assistant_tokens'])
config_info += f" num_assistant_tokens {gen_config.num_assistant_tokens}"
if args.get('assistant_confidence_threshold', None):
- gen_config.assistant_confidence_threshold = args['assistant_confidence_threshold']
+ gen_config.assistant_confidence_threshold = float(args['assistant_confidence_threshold'])
config_info += f" assistant_confidence_threshold {gen_config.assistant_confidence_threshold}"
log.info(config_info)
start = time.perf_counter()
@@ -339,14 +331,6 @@ def token_printer():
log.warning(f"[{num}] Prompt[{prompt_index}]'s md5 {result_md5_list} "
f"is different from md5 of the {num - 1} iteration {prev_md5}")
metrics_print.print_generated(num, warm_up=(num == 0), generated=generated_text[0], prompt_idx=prompt_index)
- if not args.get("use_cb", False):
- if num == 1:
- # if the device is CPU, throw exception
- if args['devices'].lower().startswith('cpu') is True:
- assert (result_md5_list == prev_md5)
- else:
- # throw exception
- assert (result_md5_list == prev_md5)
else:
metrics_print.print_generated(num, warm_up=(num == 0), generated=generated_text[0], prompt_idx=prompt_index)
@@ -461,14 +445,6 @@ def run_text_generation_genai_with_stream(input_text, num, model, tokenizer, arg
log.warning(f"[{num}] Prompt[{prompt_index}]'s md5 {result_md5_list} "
f"is different from md5 of the {num - 1} iteration {prev_md5}")
metrics_print.print_generated(num, warm_up=(num == 0), generated=generated_text[0], prompt_idx=prompt_index)
- if not args.get("use_cb", False):
- if num == 1:
- # if the device is CPU, throw exception
- if args['devices'].lower().startswith('cpu') is True:
- assert (result_md5_list == prev_md5)
- else:
- # throw exception
- assert (result_md5_list == prev_md5)
else:
metrics_print.print_generated(num, warm_up=(num == 0), generated=generated_text[0], prompt_idx=prompt_index)
streamer.reset()
diff --git a/tools/llm_bench/task/visual_language_generation.py b/tools/llm_bench/task/visual_language_generation.py
index 068ae0cf60..a5fb0ecc0c 100644
--- a/tools/llm_bench/task/visual_language_generation.py
+++ b/tools/llm_bench/task/visual_language_generation.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright (C) 2023-2024 Intel Corporation
+# Copyright (C) 2023-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import time