Goal
Helm-chart functions get no cache reuse. Customers predominantly deploy Helm
charts, so this is the main deployment mode, not an edge case. Every worker in a
release downloads the model and recompiles its kernels independently. The goal is
that one worker warms, and every other worker reads what it produced.
nvsnap is the only component that can do this. NVCA's model cache covers NGC
registry models only: not HuggingFace, not custom model endpoints, and not
compile artifacts at all. nvsnap never asks what to cache, it snapshots what the
workload wrote, which is why it covers all three. Nothing here proposes changing
NVCA.
What is already proven
Measured on dev1, 2026-09-24, two identical vLLM TP=2 pods on different nodes,
each warmed to Ready and then sent an identical inference so first-request JIT
fired.
Cache content is shareable:
model/hub 15 files 2100.43 MB byte-identical
cache/.triton 60 files 5.26 MB keys identical, 2 PTX differ by 2-3 bytes
cache/torchinductor 30 files 1.61 MB keys identical, 12 leaf names differ
96 of 108 paths identical, 37 of 37 compile-cache keys identical
The model, which is 99.9 percent of the bytes, is byte-identical. Compilation
output is not deterministic, but the cache keys are, and a hit depends on the key
rather than on the bytes. Byte-identical trees were never the requirement.
The capture is complete. All seven redirected caches land inside the captured
directory, including FlashInfer, which arrives under the HOME redirect at
/opt/nvsnap/cache/.cache/flashinfer and needs no variable of its own. The
/root/.cache/flashinfer and /root/.cache/pip directories are image-baked, not
runtime output. /tmp/root/cutlass_python_cache is empty.
What is missing, in dependency order
1. The capture trigger is unobservable, and did not fire
A pod that satisfies every documented precondition was not captured: label
nvsnap.io/capture=true, PodReady True, 2 GPUs, correct node, correct namespace,
watcher confirmed running on that node with --rootfs-capture. No capture
manifest appeared and no rootfsonly log line was emitted in 15 minutes, across
pod creation with the label and a later label remove and re-add.
The reason it cannot be diagnosed is in internal/rootfsonly/watcher.go. Every
early return in handlePodEvent is silent, and the one Info line is gated on
gpus < 2:
if !w.isLabeledForCapture(pod) { return }
if !IsPodReady(pod) { return }
if gpus < 2 { log.Info("...single-GPU pod...") }
if _, already := w.captured.LoadOrStore(pod.UID, struct{}{}); already { return }
go w.runCapture(ctx, pod.DeepCopy())
For the multi-GPU case this path exists to serve, a silently skipped capture is
indistinguishable from one that was never triggered. runCapture logs on commit
and on failure; neither appeared.
The leading hypothesis is the captured sync.Map, which is keyed by pod UID and
cleared only by EnsureRetryable, so a UID marked by an attempt that then bailed
is a permanent no-op. That is a hypothesis, not a finding, and it cannot be
confirmed without instrumenting the agent, which is the point.
This blocks everything below: election and identity are irrelevant if the trigger
does not fire or cannot be diagnosed when it does not.
2. Chart pods are never decorated
cacheDirCapturePatches is opt-in on nvsnap.io/capture=true, and the comment
names the case:
// Un-labeled pods (system/infra, helm-chart miniservice,
// anything not meant for capture) are left untouched.
Observed directly: without the label the pod keeps HF_HOME from the image, the
model lands in /root/.cache, and /opt/nvsnap is not mounted. Nothing is
captured and nothing is shareable.
3. Nothing elects a single downloader
Capture is triggered by labelling one pod, which is an explicit step for
container functions. A Helm release has no such step, so either every worker
cold-starts, or every worker waits and none warms. The wait gate already exists:
nvsnap-l2-wait is prepended at init index 0 and blocks until the capture is
promoted. What is missing is a release-scoped decision, made before consumers
start, that inspects the rendered chart, identifies which workload downloads, and
elects one warmer.
4. The sharing key is not stable across workers
composeEngineCompatFlags hashes Command and Args wholesale and positionally, so
workers differing only in node rank or leader address produce different hashes
and miss each other's capture. Either normalise the rank-bearing arguments or let
the identity be declared.
Note that Compose() is spec-derived, not content-derived, despite
checkpointstore's package comment calling the store content-addressed. Two
captures of the same spec share a hash whatever their bytes.
5. Storage selection is not agnostic
Partly addressed by #2100, which stops promoting on capability an unqualified
driver never proved. The rest is to stop holding a second opinion about the same
StorageClasses: NVCA publishes qualified access modes in the
nvcf-storage-capabilities ConfigMap, key storage-provider-capabilities.yaml,
installed by the NVCA chart with an embedded fallback. nvsnap can read it at
runtime, keeping its own behavioural fields (snapshotClass,
volumeHandleTransform, mountOptions) which the capability catalog does not
express. That is a read of an existing ConfigMap, not a change to NVCA, and the
two Go modules stay independent.
Still unmeasured
Whether a fresh pod handed a warm cache reuses it or recompiles. The key match
above is strong indirect evidence; the direct test is to mount one worker's cache
into a new pod and confirm no new compile keys appear. Blocked on item 1.
Whether ranks that legitimately differ produce divergent compile caches. Every
workload in the repository is single-pod, so this needs a multi-pod chart built
first. Symmetric tensor parallelism should match; pipeline or expert parallelism
may not.
Sequence
- Make the capture trigger observable, and find out why it did not fire.
- Prove reuse: warm, capture, restore into a fresh pod, confirm no recompile.
- Decorate and elect for chart pods.
- Stabilise the sharing key across ranks.
- Catalog-derived storage selection.
References
Relates to #1009
Relates to #2100
Goal
Helm-chart functions get no cache reuse. Customers predominantly deploy Helm
charts, so this is the main deployment mode, not an edge case. Every worker in a
release downloads the model and recompiles its kernels independently. The goal is
that one worker warms, and every other worker reads what it produced.
nvsnap is the only component that can do this. NVCA's model cache covers NGC
registry models only: not HuggingFace, not custom model endpoints, and not
compile artifacts at all. nvsnap never asks what to cache, it snapshots what the
workload wrote, which is why it covers all three. Nothing here proposes changing
NVCA.
What is already proven
Measured on dev1, 2026-09-24, two identical vLLM TP=2 pods on different nodes,
each warmed to Ready and then sent an identical inference so first-request JIT
fired.
Cache content is shareable:
The model, which is 99.9 percent of the bytes, is byte-identical. Compilation
output is not deterministic, but the cache keys are, and a hit depends on the key
rather than on the bytes. Byte-identical trees were never the requirement.
The capture is complete. All seven redirected caches land inside the captured
directory, including FlashInfer, which arrives under the HOME redirect at
/opt/nvsnap/cache/.cache/flashinferand needs no variable of its own. The/root/.cache/flashinferand/root/.cache/pipdirectories are image-baked, notruntime output.
/tmp/root/cutlass_python_cacheis empty.What is missing, in dependency order
1. The capture trigger is unobservable, and did not fire
A pod that satisfies every documented precondition was not captured: label
nvsnap.io/capture=true, PodReady True, 2 GPUs, correct node, correct namespace,watcher confirmed running on that node with
--rootfs-capture. No capturemanifest appeared and no
rootfsonlylog line was emitted in 15 minutes, acrosspod creation with the label and a later label remove and re-add.
The reason it cannot be diagnosed is in
internal/rootfsonly/watcher.go. Everyearly return in
handlePodEventis silent, and the one Info line is gated ongpus < 2:For the multi-GPU case this path exists to serve, a silently skipped capture is
indistinguishable from one that was never triggered.
runCapturelogs on commitand on failure; neither appeared.
The leading hypothesis is the
capturedsync.Map, which is keyed by pod UID andcleared only by
EnsureRetryable, so a UID marked by an attempt that then bailedis a permanent no-op. That is a hypothesis, not a finding, and it cannot be
confirmed without instrumenting the agent, which is the point.
This blocks everything below: election and identity are irrelevant if the trigger
does not fire or cannot be diagnosed when it does not.
2. Chart pods are never decorated
cacheDirCapturePatchesis opt-in onnvsnap.io/capture=true, and the commentnames the case:
Observed directly: without the label the pod keeps
HF_HOMEfrom the image, themodel lands in
/root/.cache, and/opt/nvsnapis not mounted. Nothing iscaptured and nothing is shareable.
3. Nothing elects a single downloader
Capture is triggered by labelling one pod, which is an explicit step for
container functions. A Helm release has no such step, so either every worker
cold-starts, or every worker waits and none warms. The wait gate already exists:
nvsnap-l2-waitis prepended at init index 0 and blocks until the capture ispromoted. What is missing is a release-scoped decision, made before consumers
start, that inspects the rendered chart, identifies which workload downloads, and
elects one warmer.
4. The sharing key is not stable across workers
composeEngineCompatFlagshashes Command and Args wholesale and positionally, soworkers differing only in node rank or leader address produce different hashes
and miss each other's capture. Either normalise the rank-bearing arguments or let
the identity be declared.
Note that
Compose()is spec-derived, not content-derived, despitecheckpointstore's package comment calling the store content-addressed. Twocaptures of the same spec share a hash whatever their bytes.
5. Storage selection is not agnostic
Partly addressed by #2100, which stops promoting on capability an unqualified
driver never proved. The rest is to stop holding a second opinion about the same
StorageClasses: NVCA publishes qualified access modes in the
nvcf-storage-capabilitiesConfigMap, keystorage-provider-capabilities.yaml,installed by the NVCA chart with an embedded fallback. nvsnap can read it at
runtime, keeping its own behavioural fields (
snapshotClass,volumeHandleTransform,mountOptions) which the capability catalog does notexpress. That is a read of an existing ConfigMap, not a change to NVCA, and the
two Go modules stay independent.
Still unmeasured
Whether a fresh pod handed a warm cache reuses it or recompiles. The key match
above is strong indirect evidence; the direct test is to mount one worker's cache
into a new pod and confirm no new compile keys appear. Blocked on item 1.
Whether ranks that legitimately differ produce divergent compile caches. Every
workload in the repository is single-pod, so this needs a multi-pod chart built
first. Symmetric tensor parallelism should match; pipeline or expert parallelism
may not.
Sequence
References
Relates to #1009
Relates to #2100