Skip to content

Propagate global --cache_dir to continuous batching pipeline (#4230)#4329

Open
exzile wants to merge 6 commits into
openvinotoolkit:mainfrom
exzile:fix/cache-dir-continuous-batching
Open

Propagate global --cache_dir to continuous batching pipeline (#4230)#4329
exzile wants to merge 6 commits into
openvinotoolkit:mainfrom
exzile:fix/cache-dir-continuous-batching

Conversation

@exzile

@exzile exzile commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #4230.

The continuous batching servable initializer constructs the GenAI ContinuousBatchingPipeline directly and never applied the server-level --cache_dir (ServerSettings.cacheDir). Unlike the non-CB path — which applies it via ModelInstance::setCacheOptions (ieCore.set_property(ov::cache_dir(...))) — the CB path left model-compilation caching disabled unless the user manually duplicated the value into the node's plugin_config as CACHE_DIR. As a result, .blob/.cl_cache artifacts were never persisted and every server restart fully recompiled the model.

Fix

In ContinuousBatchingServableInitializer::initialize, inject the global cache_dir into the pipeline pluginConfig (keyed by ov::cache_dir.name() == CACHE_DIR) right after parsing the node plugin_config and before constructing the pipeline. An explicit CACHE_DIR in the node's plugin_config remains authoritative.

const std::string& globalCacheDir = Config::instance().cacheDir();
if (!globalCacheDir.empty()) {
    if (properties->pluginConfig.find(ov::cache_dir.name()) == properties->pluginConfig.end()) {
        properties->pluginConfig[ov::cache_dir.name()] = globalCacheDir;
    } // else: explicit node CACHE_DIR wins
}

This also applies to the VLM continuous-batching servable, which reuses this initializer.

Testing

Added a regression test LLMNodeOptionsCacheDirPropagation (run for both the CB and VLM fixtures) covering:

  1. The global --cache_dir is propagated into pluginConfig["CACHE_DIR"] when the node does not set it.
  2. An explicit CACHE_DIR in the node plugin_config takes precedence over the global value.

Built and ran locally on Windows (MSVC) against a real facebook/opt-125m continuous-batching pipeline:

[       OK ] LLMOptionsHttpTest.LLMNodeOptionsCheckPluginConfig
[       OK ] LLMOptionsHttpTest.LLMNodeOptionsCacheDirPropagation
[  PASSED  ] 2 tests.

🤖 Generated with Claude Code

@exzile

exzile commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

End-to-end verification on GPU

Beyond the unit test, I verified the actual caching behavior on an Intel Arc Pro B70 dGPU (EXPORT_IMPORT capable) serving facebook/opt-125m via continuous batching with device: "GPU" and a --cache_dir pointing at an initially-empty directory:

Run 1 (empty cache):

  • Log confirms the fix path: servable_initializer.cpp] Applying global cache_dir to continuous batching pipeline: .../cachedir
  • Cache dir went from empty → *.cl_cache files + a 130 MB .blob (compiled model)
  • Pipeline init → AVAILABLE: ~1.6 s

Run 2 (restart, populated cache):

  • Same fix path fires
  • No recompile: blob is reused (file unchanged), no new artifacts written
  • Pipeline init → AVAILABLE: ~0.24 s (~6.7× faster cold start)

Without the change the cache directory stays empty on the CB path and every restart recompiles. With it, blobs persist and are reused across restarts as intended.

The continuous batching servable initializer constructs the GenAI
ContinuousBatchingPipeline directly and never applied the server-level
--cache_dir (ServerSettings.cacheDir). Unlike the non-CB path, which
applies it via ModelInstance::setCacheOptions, the CB path left model
compilation caching disabled unless the user duplicated the value into
the node's plugin_config as CACHE_DIR. As a result, .blob/.cl_cache
artifacts were never persisted and every restart fully recompiled the
model.

Inject the global cache_dir into the pipeline plugin config before
constructing the pipeline. An explicit CACHE_DIR in the node's
plugin_config remains authoritative.

Adds a regression test (LLMNodeOptionsCacheDirPropagation) covering both
propagation of the global value and precedence of an explicit node value.

Fixes openvinotoolkit#4230

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@exzile exzile force-pushed the fix/cache-dir-continuous-batching branch from 6fd48db to c45573c Compare June 27, 2026 01:04
LLMNodeOptionsCacheDirPropagation only asserts that --cache_dir lands in
properties->pluginConfig, which doesn't prove OpenVINO Core actually persists
compiled-model cache artifacts -- the actual symptom in openvinotoolkit#4230 (log said
"cache enabled", nothing was ever written to disk). Addresses feedback on
the issue: openvinotoolkit#4230 (comment)

LLMNodeOptionsCacheDirWritesCacheArtifacts constructs a real
ContinuousBatchingPipeline against a temp --cache_dir and asserts at least
one cache file actually lands there. Verified locally on Windows (MSVC)
against facebook/opt-125m:

[       OK ] LLMOptionsHttpTest.LLMNodeOptionsCacheDirWritesCacheArtifacts (707 ms)
@dtrawins dtrawins requested review from dkalinowski and mzegla July 9, 2026 09:44
Comment thread src/test/llm/llmnode_test.cpp Outdated
Comment thread src/llm/language_model/continuous_batching/servable_initializer.cpp Outdated
exzile and others added 2 commits July 9, 2026 09:27
Extract the global --cache_dir propagation into a shared
GenAiServableInitializer::applyGlobalCacheDir helper and call it from all
GenAI initializers. The continuous batching path already applied it (and
VLM_CB shares that same initializer), but the legacy LM and legacy VLM
paths construct their pipelines directly and never applied the
server-level cache_dir. Routing every path through one helper covers all
four pipeline types (LM/VLM x CB/legacy) and removes the duplicated
inline block from the CB initializer.

In the cache_dir tests, replace the manual end-of-test Config restore
with a GlobalCacheDirGuard RAII helper so a failed ASSERT mid-test can no
longer leak the modified --cache_dir singleton into subsequent tests in
the suite. The guard also removes the temporary cache directory on scope
exit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR restores the server-level --cache_dir behavior for GenAI servables by propagating it into the OpenVINO GenAI pipeline pluginConfig (unless explicitly overridden by node plugin_config), ensuring compiled-model cache artifacts can persist across restarts for LLM/VLM pipelines.

Changes:

  • Add GenAiServableInitializer::applyGlobalCacheDir() to inject the global --cache_dir into GenAI pipeline plugin properties when CACHE_DIR is not explicitly set per node.
  • Call applyGlobalCacheDir() from LM/VLM initializers (legacy + continuous batching) before constructing GenAI pipelines.
  • Add regression tests for cache-dir propagation (and an end-to-end cache artifact write check), plus documentation clarifying behavior.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/test/llm/llmnode_test.cpp Adds tests verifying --cache_dir propagation and precedence, plus an end-to-end artifact write assertion.
src/llm/visual_language_model/legacy/servable_initializer.cpp Applies global cache dir before creating ov::genai::VLMPipeline.
src/llm/servable_initializer.hpp Declares applyGlobalCacheDir() helper on the shared initializer base.
src/llm/servable_initializer.cpp Implements applyGlobalCacheDir() using Config::instance().cacheDir() and ov::cache_dir.name().
src/llm/language_model/legacy/servable_initializer.cpp Applies global cache dir before creating ov::genai::LLMPipeline.
src/llm/language_model/continuous_batching/servable_initializer.cpp Applies global cache dir before creating ov::genai::ContinuousBatchingPipeline.
docs/model_cache.md Documents cache-dir behavior for GenAI/LLM pipelines and precedence rules.

Comment thread src/test/llm/llmnode_test.cpp
Comment thread src/test/llm/llmnode_test.cpp
Comment thread docs/model_cache.md
exzile and others added 2 commits July 16, 2026 00:25
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@rasapala rasapala self-requested a review July 16, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

--cache_dir not propagated to LLM continuous batching pipeline (regression vs 2025.4 promise)

3 participants