feat(llamacpp): add fuse delivery mode (read-only object-store PVC mount) - #1532
Draft
mhotan wants to merge 2 commits into
Draft
feat(llamacpp): add fuse delivery mode (read-only object-store PVC mount)#1532mhotan wants to merge 2 commits into
mhotan wants to merge 2 commits into
Conversation
mhotan
force-pushed
the
mike/llamacpp-fuse-delivery
branch
2 times, most recently
from
September 4, 2026 11:09
ec2f862 to
3e2a605
Compare
…unt) Add model_delivery="fuse" to LlamaCppAppEnvironment: instead of downloading the bound weights into the pod's local disk, read them in place from a read-only, object-store-backed PVC (gcsfuse on GKE, Mountpoint-S3 on EKS). Lazy first-touch, nothing copied to local disk, and the mount releases cleanly on scale-to-zero, so scale-from-zero is bounded by GPU node cold-start rather than re-downloading the model. A PVC is Knative-friendly and, unlike a node device-plugin (JuiceFS / Union Volume), does not block scale-to-zero. The PVC is cloud infrastructure provisioned outside the SDK; the app names a relative subpath under it via model_path. New knobs: model_pvc, model_mount_path, fuse_pod_annotations. Attaches the PVC volume/mount to the primary "app" container (idempotent under clone_with) and emits no download Parameters. Examples, one per CSI driver: llamacpp_app_gcsfuse.py (GKE, sets the gcsfuse sidecar annotation) and llamacpp_app_mountpoint_s3.py (EKS, mounts the static PV directly, no annotation). Each demonstrates the full loop: a Flyte run (hf_model) creates a versioned Model artifact under the FUSE-visible prefix, the run's artifact URI is stripped of the mounted prefix to derive the subpath, and the app streams exactly that artifact in place via FUSE -- no download. README adds a download-vs-fuse comparison. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Michael Hotan <mike@union.ai>
…d draft find_gguf globbed **/*.gguf recursively and returned the lexically-first match, so a --model-dir pointing at a directory that also holds the draft/MTP GGUF in a subdirectory resolved the model to the draft (e.g. an object-store FUSE prefix carrying both Model.gguf and MTP/draft.gguf -- "MTP" sorts before the model name). Download mode never hit this because model and draft are separate artifacts in separate mount dirs; fuse delivery surfaces them under one prefix. Prefer GGUFs directly in the given directory and only recurse when none are found there; sharded-shard and nested-only layouts are unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Michael Hotan <mike@union.ai>
mhotan
force-pushed
the
mike/llamacpp-fuse-delivery
branch
from
September 4, 2026 11:44
d7b9291 to
8606b90
Compare
mhotan
changed the base branch from
mike/prefetch-hf-model-file-selection
to
mike/llamacpp-cuda-image-fixes
September 4, 2026 11:44
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Give
LlamaCppAppEnvironmenta scale-to-zero-clean way to serve large GGUF weights. Today the plugin only downloads the bound model into the pod's local disk beforellama-serverstarts — the whole GGUF (up to ~18 GB) lands on ephemeral disk and the copy is on the cold-start path. This adds a lazy FUSE-mount delivery so scale-from-zero is bounded by GPU node cold-start, not by re-downloading the model.Root cause it works around:
flyte/app/_parameter.pyforcesdownload=Truewhenevermount=is set for aDir/ArtifactValue/RunOutput, so there is no way to make a bound model available at a path without copying it to local disk. Rather than reworking that core primitive, this re-leverages the proven, Knative-friendly path: a static, CSI-backed read-only PVC attached viapod_template.What changed
model_delivery: Literal["download", "fuse"]onLlamaCppAppEnvironment(default"download"— existing behavior unchanged)."fuse"mode: reads weights in place from a read-only, object-store-backed PVC (gcsfuse on GKE, Mountpoint-S3 on EKS). New knobs:model_pvc,model_mount_path(default/tmp/models),fuse_pod_annotations.model_path/draft_model_pathbecome relative subpaths under the mount.appcontainer and emits no downloadParameter. Idempotent underclone_with(which re-runs__post_init__). Validation rejectsmodel_hf_path, boundArtifactValue/RunOutput, or a missingmodel_pvcin fuse mode; and the fuse-only knobs in download mode.PersistentVolumeClaimis on Knative's podspec allow-list and releases cleanly on scale-down; a node device-plugin (JuiceFS / Union Volume) pins the node and blocks scale-to-zero.examples/genai/llamacpp/llamacpp_app_gcsfuse.py(GKE — sets thegke-gcsfuse/volumes: "true"sidecar annotation) andllamacpp_app_mountpoint_s3.py(EKS — mounts the static PV directly, no annotation). Each demonstrates the full loop: a Flyte run (hf_model) creates a versioned Model artifact under the FUSE-visible prefix, the run's artifact URI is stripped of the mounted prefix to derive the subpath, and the app streams exactly that artifact in place via FUSE — no download. README adds a download-vs-fuse comparison.How it was tested
pytest plugins/llamacpp/tests→ 48 passed (9 new fuse tests; existing 39 unchanged).pod_specsanitizes to the exact k8s shape the CSI driver needs (RO PVC volume + ROvolumeMountonapp, gcsfuse sidecar annotation).ruff check/ruff format --check/check_docstring_style.pyall clean.internal-flyte-apps(gcsfuse RO PVC serving a real GGUF, scale-to-zero-clean).Stack
Part of a linear stack — merge in order:
main← #1528 (prefetchallow_patterns) ← #1531 (CUDA image build fix) ← #1532 (this PR).This PR is based on #1531: fuse mode reuses the plugin's
build_llama_cpp_image(fixed in #1531), and the examples compose #1528'shf_model(allow_patterns=…)filtered prefetch with this PR's fuse mount.