Repository navigation
docs(flash): move the flash lane to the Runpod SDK 2.0 (rp flash) - #89
justinwlin wants to merge 19 commits into
Conversation
c741380 to
20150f5
Compare
20150f5 to
bcb59eb
Compare
bcb59eb to
4cbbe30
Compare
Flash ships in runpod 2.0 as SDK apps (runpod.App, @app.queue/@app.api/@app.task) with the rp CLI, and runpod-flash is deprecated on October 29, 2026. - flash skill: SDK-first SKILL.md, setup/CLI, API and patterns references checked against runpod 2.0.0rc1 (--help, source, sdk-runtime) - new references: migrate-from-runpod-flash.md, runpod-flash-legacy.md - examples/: five single-file apps, each passing rp flash deploy --build-only - evals rewritten for the SDK, plus a migration eval; dev-loop fixture now fails on a missing dependency (the body-only NameError no longer exists) - flash concept rules rewritten with public docs/source evidence; citing rules in flashboot, job, model-store, runpodctl, serverless-handler and volume-cache updated - router, READMEs, getting-started and endpoint/pod references use rp - golden paths 03-B, 07, 08 ported to the SDK and marked ported (build-only checked; the live runs used runpod-flash)
A non-interactive shell starts & jobs with SIGINT ignored, and SIGTERM exits rp flash dev without deleting its temporary endpoints. Verified live: the python exec wrapper restores SIGINT and the session reports its endpoints deleted.
- examples: queue_gpu, api_model_service and cpu_gpu_pipeline pass rp flash dev --once live; cpu_gpu_pipeline now casts to float32 because whole-number floats cross the job boundary as ints - golden path 03-B live-verified on the SDK; pin av<19 (PyAV 19 dropped the metadata_errors argument faster-whisper passes) - gotcha 14: dev-session runtime images predate runpod.NetworkVolume, so volume apps (train_then_serve, golden paths 07 and 08) fail in rp flash dev
Deployed SDK workers attach the network volume, but on the current runtime images vol.path raises 'is not mounted in the current execution'. Reading the literal mount path works: on 2026-10-16 one deployed endpoint wrote to a volume and another read the exact contents back. Golden paths 07 and 08 and train_then_serve.py now read literal paths and run via rp flash deploy.
…ment deploy crash loop - golden path 08 serve step verified via rp flash deploy (TinyLlama + LoRA from a network volume); call_deployed.py verified against deployed apps - gotcha 13: torch-dependent packages (peft, accelerate, sentence-transformers) vendor a CUDA 13 torch that replaces the image's and crash-loops GPU workers (libcudart.so.13); install them with pip --no-deps at runtime (08 shows how) - patterns.md drops accelerate from GPU examples for the same reason - api.md: rp flash deploy maps GPU names to whole pools; pin after deploy - concept rules flash.transitive-torch-breaks-gpu-deploy and flash.deploy-gpu-names-map-to-pools with live-probe evidence
The volume version could not run in a dev session on the current runtime images. The task now returns its weights as JSON to the queue endpoint (the volume handoff is covered by golden path 07). Verified 2026-10-16 with rp flash dev --once: the task Pod trained, predict returned f(2.0) = 7.00, and the Pod and endpoint were cleaned up.
Assumes runpod 2.0.0rc2, which carries the SDK fixes for these issues: - The build leaves torch out even when a dependency pulls it in, so golden path 08 lists peft and accelerate directly and the --no-deps workaround and its gotcha are gone. - GPU device names pin exact devices, so the set-endpoint-gpus advice is gone. - vol.path works on deployed workers. - Dev sessions clean up on kill or SIGINT, so the SIGINT wrapper is gone. - Only workers that call other resources get the API key. Install pins move to runpod>=2.0.0rc2. Concept rules are replaced to match.
runpod 2.0.0rc2 was cut before the build, GPU-pinning, dev-signal and vol.path fixes merged, so the docs now pin the next release, 2.0.1. The change that limited RUNPOD_API_KEY to endpoints that call other resources (runpod-python #628, then #641) was closed unmerged. Deploy and dev add the key to every endpoint, so flash.worker-api-key-for-callers is replaced by flash.worker-api-key-every-endpoint, cited to the SDK source, and api.md, the migration guide and golden path 08 say the same.
4cbbe30 to
4d00f66
Compare
Flash in the Runpod SDK can still hit SDK bugs that runpod-flash handled. The flash skill now says how to tell an SDK failure from a code failure, where to look for a fix (runpod-python CHANGELOG and runpod/apps commit history, runpod-flash history), and how to fall back: install runpod-flash as an isolated uv tool with runpod<2 and deploy the pre-migration code. The migration guide keeps the old endpoints until the new ones pass. New rule flash.legacy-fallback (live-verified side-by-side install) and eval sdk-failure-fallback.
Concept evidence now points at the code on runpod-python main rather than pull requests, the README install pin moves to runpod>=2.0.1, and golden path 08's status no longer lists the fixes the test build carried.
f02e97c to
6411449
Compare
OneAsterisk
left a comment
There was a problem hiding this comment.
Claude review, round 1
Verdict: Needs changes. The SDK port is accurate against runpod-python source, but the PR is not a draft and its install pin does not resolve yet.
Approval gate: 0 Critical, 1 High, 15 Medium+Low → not approved (High finding, and Medium+Low ≥ 10).
Existing feedback
No prior reviews, inline comments or conversation comments. CI: all required checks pass (pytorch-pod-lifecycle and template-examples skipped by path filter).
PR description vs code
| Claim | Status | Where |
|---|---|---|
| Skill rewritten SDK-first, detects which SDK, migrate and legacy references | ✅ | flash/SKILL.md:34-45,76-77 |
| Five single-file apps, all passing live | Checked on 2.0.0rc1 (examples/README.md:12), before the GPU-pinning fix the docs now describe |
|
| Golden paths 03-B, 07, 08 re-verified live | 08's run used VolumeCache code from #90, not the code in the file. See Medium 4 |
|
| One-file rule scoped to dev sessions | Done in SKILL.md:122-124,175-177 and flash.yaml. Missed at migrate-from-runpod-flash.md:39 |
|
| 300 s queue timeout, tasks have none | ✅ | api.md:60, flash.yaml, 03-B; SDK targets.py:28, tasks.py |
| API key copied to every endpoint, documented | ✅ | flash.worker-api-key-every-endpoint; SDK deploy.py:315, dev.py:146 |
flash.legacy-fallback rule and sdk-failure-fallback eval |
✅ | flash.yaml:41, evals/sdk-failure-fallback.eval.md |
| Merge after 2.0.1 is on PyPI | Correct gate, but the PR is open for review, not draft. See High |
Findings
High
- Install pin does not resolve:
runpod2.0.1 is not on PyPI —flash/SKILL.md:79. PyPI has 1.12.0 and 2.0.0rc2; release PR runpod/runpod-python#594 is open. Merging now breaks 17 install lines in 12 files. Convert to draft until 2.0.1 ships.
Medium
class SDfailsrp flash deploy—reference/patterns.md:43. Deploy rejects queue and API names under 3 characters (deploy.py:133-137); dev does not check. Same forname="x"atmigrate-from-runpod-flash.md:61. Rename, and add the 3-character rule as a gotcha.- Migration guide contradicts the one-file scoping —
migrate-from-runpod-flash.md:39. Says "Discovery ships one module per app". Deploy packages the project directory (deploy.py:183-229). - Migration uninstalls the CLI it needs later —
migrate-from-runpod-flash.md:50removesrunpod-flash, but step 6 (:158) and the rollback (:15-18) needflash. Install it withuv tool installin step 3 first. - Verification status overstates what ran —
golden-paths/README.md:78,08-finetune-to-serverless.md:17-22,examples/README.md:12. 08's SDK run used the #90VolumeCachecode on a local build. Examples ran on rc1. The new 🔄 ported status (README.md:139-141) is defined but used by no row.
Low
examples/cpu_gpu_pipeline.py:36runs the CPU stage serially, failing its own eval (cpu-gpu-pipeline.eval.md:26).examples/queue_gpu.py:20omitsdtype=torch.float32, contradicting gotcha 1.SKILL.md:194"Local Python must be 3.10–3.14": deploy falls back to 3.12 with a warning (rp_cli/main.py:190-198). Only dev and tasks require it. Same inflash.yaml.migrate-from-runpod-flash.md:77:max_concurrencyexists only on@app.queue(app.py:93).@app.taskalso lacksidle_timeout,flashboot,scaler_*.setup-and-cli.md:94:DEFAULT_IGNORES(deploy.py:35-53) always dropstests/,test_*.py,*_test.py,env/. Atest_utils.pyhelper vanishes at deploy.08-finetune-to-serverless.md:182hardcodesdatacenter="EU-RO-1"; step 1 creates the volume in<dc>. Cleanup (:240) also lacksrp flash app delete ft-serve --yes.SKILL.md:3-9description is three sentences (AGENTS.md rule 2: 1–2).- "is deprecated on October 29, 2026" (
SKILL.md:26,migrate…md:7,runpod-flash-legacy.md:9,flash.yaml:33). The docs say deprecated now, fixes stop October 29.SKILL.md:25also adds "now". migrate-from-runpod-flash.md:145-147: "runpod-flash added it only to endpoints that made remote calls" has no backing rule (AGENTS.md rule 12).- The
runpod>=2.0.1pin appears in 13 files plus 3 "Fromrunpod2.0.1" rules. Swapping it means 20 edits. Keep it inflash.part-of-runpod-sdkandsetup-and-cli.mdonly.
Nits
SKILL.md:212andflash.yaml:162:rp flash app delete APPaborts without a TTY (click.confirm(abort=True)). Add--yes.migrate-from-runpod-flash.md:50:pip uninstallprompts. Add-y.SKILL.md:105,api.md:56-65:streamandwith_optionsare queue-only (handles.py:96-100,191-193); task.spawn()returns aTaskJob.SKILL.md:172:arguments must be json-serializableis dev-only; deployed calls raise the stdlibTypeError.connect-existing-endpoint.eval.md:21-23:run_syncpasses a pre-wrapped{"input": ...}through unchanged (runner.py:236), and its default timeout is 86400, not 60.07-network-volume-handoff.md:94reads the literal/runpod-volume, while gotcha 8 says to readvol.path.SKILL.mdgotchas never mention the API key on every endpoint; it lives only inapi.md:186-191.
Simplification opportunities
- The fallback procedure appears four times (
SKILL.md:47-60,migrate…md:15-21,runpod-flash-legacy.md:7-15,flash.yaml:41-49). Keep a 2-line pointer in SKILL.md and the steps in the legacy reference (~15 lines). Fine in this PR. - Centralize the version pin (Low 10). About 18 edits now, 1 per future bump.
Verified clean
- Every decorator parameter and default in
api.mdagainstapp.py/spec.py(workers(0, 3),idle_timeout60,flashboot, disk sizes), andgpu/cpuexclusivity. - Dev loop:
--onceexit code, closed-stdin re-run, SIGINT/SIGTERM cleanup, second-signal force stop,dev-<app>-<res>-<hash>names, and the✓ done in/✗ failed in/cleaning uplog strings. - CLI surface (
rp login,rp update, everyrp flashsubcommand and flag,rp secret,rp registry,rp logs). - Torch-family pruning, 1,500 MB artifact limit,
vol.pathworker-only, one volume per queue/API resource. - All
flash.yamlevidence URLs atv2.0.0rc1andfc4a6c7point at code that says what the note claims. - Examples compile, use real exports and kwargs, and contain no hardcoded keys. Relative links resolve. No "RunPod". No stale
runpod_flashinstructions outside labelled history.
Questions for the author
- Will #594 ship #623–#626 under 2.0.1? If not, which version should the pin name?
- Was the
uv tool install runpod-flash --with "runpod<2"fallback tested on a project with its own local imports (numpy, etc.)? The tool venv only holdsrunpod-flashandrunpod1.x. - Legacy
runpod-flashclaims (CLI flags, 1.21.0 notice, API key on calling endpoints only) were not checked; that source was not available to this review.
Reviewed by Claude (claude-opus-5-5) via the pr-review skill. Tokens: 334 in / 14,430 out / 14,286,149 cache read / 486,330 cache write = 14,787,243. Estimated cost: $14.02 at the rate table in the skill's sum_usage.py, 5-minute cache writes assumed. Round 1 of this PR. This is automated assistance; a human owns the final call.
| develop. | ||
| - `flash deploy` — **ship.** Builds an artifact and deploys a stable endpoint. Slow | ||
| (build + upload + provision); only do this once the code works under `flash dev`. | ||
| Quick start: `uv add "runpod>=2.0.1"` (or `pip install "runpod>=2.0.1"`) → `rp login` (or `export RUNPOD_API_KEY=...`) |
There was a problem hiding this comment.
High: runpod 2.0.1 is not on PyPI (latest 1.12.0, pre-release 2.0.0rc2; release PR runpod/runpod-python#594 is open). Pre-releases are excluded by default and rc2 < 2.0.1, so this line and 16 other install lines fail with "No matching distribution" if merged now. Convert the PR to draft until 2.0.1 ships.
There was a problem hiding this comment.
Verified addressed at 5925d7d: the PR is now a draft. PyPI still tops out at 1.12.0 / 2.0.0rc2 and runpod/runpod-python#594 is open, so keep the merge-after-2.0.1 gate.
There was a problem hiding this comment.
Reopened at 9451b6e: the PR went back to ready for review on 2026-10-23, but PyPI still tops out at 1.12.0 / 2.0.0rc2 and runpod/runpod-python#594 is open. Draft status was the mitigation in round 2, so this blocks approval again. Re-draft, or merge only after 2.0.1 is on PyPI.
There was a problem hiding this comment.
Not addressed at 1d38d89: the PR is still ready for review, PyPI still tops out at 1.12.0 / 2.0.0rc2, and runpod/runpod-python#594 is open. Re-draft, or merge only after 2.0.1 is on PyPI.
There was a problem hiding this comment.
Not addressed at 1495679: the PR is still ready for review. PyPI still tops out at 1.12.0 / 2.0.0rc2, and runpod/runpod-python#594 is open. The #90 merge added the pin to two more files (14 total). Re-draft, or merge only after 2.0.1 is on PyPI.
There was a problem hiding this comment.
Not addressed at 81c2d69: the PR is still ready for review. PyPI still tops out at 1.12.0 / 2.0.0rc2, and runpod/runpod-python#594 is open. Re-draft, or merge only after 2.0.1 is on PyPI.
There was a problem hiding this comment.
Not addressed at 4dd848e: the PR is still ready for review. PyPI still tops out at 1.12.0 / 2.0.0rc2, and runpod/runpod-python#594 is open. Re-draft, or merge only after 2.0.1 is on PyPI.
There was a problem hiding this comment.
Not addressed at 8766329: the PR is still ready for review. PyPI still tops out at 1.12.0 / 2.0.0rc2, and runpod/runpod-python#594 is open (checked 2026-10-26). Re-draft, or merge only after 2.0.1 is on PyPI.
- Deploy rejects queue/API names under 3 characters: rename the pattern's class, use a real name in the migration table, add gotcha 16 and rule flash.resource-name-min-length. - Migration guide: dev ships one module but deploy packages the project; keep `flash` installed for cleanup and rollback; -y on pip uninstall; split decorator options by kind (max_concurrency is queue-only, tasks take no scaling options). - Fallback from the SDK lives in the legacy reference, in its own venv with the project's requirements and runpod<2 (verified); SKILL.md keeps a pointer. - Verification status says what ran: examples on 2.0.0rc1, golden path 08 marked ported (its SDK run used VolumeCache), 07 notes the literal path. - Examples: float32 tensor, parallel CPU stage. - Python 3.10-3.14 applies to dev and tasks; deploy falls back to 3.12. - Default ignores drop tests and virtualenvs; stream/with_options are queue-only; the JSON error text is dev-only; app delete needs --yes. - Deprecated now, no fixes after October 29, 2026; two-sentence skill description; gotcha 17 for the API key on every endpoint.
OneAsterisk
left a comment
There was a problem hiding this comment.
Claude review, round 2
Verdict: Ready after fixes. Round 1 is fixed except the pin centralization; the new fallback venv path gets packaged into deploys. Gate passed; approve when marked ready (and after runpod 2.0.1 is on PyPI).
Approval gate: 0 Critical, 0 High, 3 Medium+Low → gate passed, but the PR is a draft, so this is a COMMENT.
Status of prior findings
| # | Finding | Severity | Status | Evidence |
|---|---|---|---|---|
| R1-H1 | runpod>=2.0.1 not on PyPI |
High | Fixed (mitigated) | PR is now draft. PyPI still tops out at 1.12.0 / 2.0.0rc2, and runpod/runpod-python#594 is open, so the "merge after 2.0.1" gate still applies |
| R1-M1 | class SD fails deploy |
Medium | Fixed | patterns.md:43 StableDiffusion, gotcha 16, new rule flash.resource-name-min-length (deploy.py#L133) |
| R1-M2 | Migration guide one-module claim | Medium | Fixed | migrate-from-runpod-flash.md:36-37 |
| R1-M3 | Migration uninstalls the CLI it needs | Medium | Fixed | migrate-from-runpod-flash.md:48-49 (uv tool install first, pip uninstall -y) |
| R1-M4 | Verification status overstated | Medium | Fixed | 08…md:17-18, golden-paths/README.md:77-78 (🔄 now used), examples/README.md:12-14 |
| R1-L1 | CPU stage serial | Low | Fixed | cpu_gpu_pipeline.py:36-37 |
| R1-L2 | missing float32 |
Low | Fixed | queue_gpu.py:20 |
| R1-L3 | Python 3.10–3.14 rule | Low | Fixed | SKILL.md:185-187, flash.yaml with main.py#L190 evidence |
| R1-L4 | max_concurrency / task params |
Low | Fixed | migrate…md:76-78; matches app.py signatures for queue (L76), task (L136), api (L180) |
| R1-L5 | DEFAULT_IGNORES undocumented |
Low | Fixed | setup-and-cli.md:94-98 matches deploy.py:35-53 |
| R1-L6 | 08 hardcoded DC, no app delete | Low | Fixed | 08…md:183,241 |
| R1-L7 | description 3 sentences | Low | Fixed | SKILL.md:3-9 is 2 sentences |
| R1-L8 | "deprecated on October 29" | Low | Fixed | all 4 sites |
| R1-L9 | unbacked runpod-flash API key claim | Low | Fixed | comparison dropped, migrate…md:146-147 |
| R1-L10 | pin repeated across files | Low | Not addressed | runpod>=2.0.1 still in 12 files, 23 2.0.1 mentions |
| R1 nits (7) | --yes, -y, queue-only stream/with_options, dev-only JSON error, eval wrapping, 07 vol.path, API key gotcha |
Nit | Fixed | SKILL.md:96-97,162-163,202-211, api.md:62-65, eval :21-22, 07…md:94-98 |
Question from round 1 on local imports in the fallback env: answered by the new uv venv + -r requirements.txt steps and the added live-probe evidence.
Existing feedback
No human or bot comments. All 15 round-1 threads were resolved before this round; each gets a verification reply. CI: all checks pass (pytorch-pod-lifecycle, template-examples skipped by path filter).
PR description vs code
| Claim | Status | Where |
|---|---|---|
| Fallback with isolated install, live-checked next to 2.x | ✅ | runpod-flash-legacy.md:31-53, flash.runpod-flash-installs-alongside evidence (now also covers -r requirements.txt) |
| "Review findings" table (300 s timeout, one-file scoping) | ✅ | unchanged from round 1 |
| Body does not mention the round-1 fixes | Not a false claim; consider adding them to the "Review findings" table |
Findings
Medium
- Fallback venv is packaged by
flash deploy—runpod-flash-legacy.md:46..venv-flashis created in the project root. runpod-flash ignores only.venv/,venv/,env/(runpod_flash/cli/utils/ignore.py:88-90), so step 2's ownflash deploybundles the whole venv. After moving back to the SDK,rp flash deploydoes the same (deploy.py:36-38), likely past the 1,500 MB limit. Create the venv outside the project. The live probe ranflash --helponly, so it did not catch this.
Low
- Committed bytecode —
flash/examples/__pycache__/*.cpython-314.pyc(5 files) arrived in 5925d7d and ship with the plugin. Remove them and add__pycache__/to.gitignore. - R1-L10, carried: the pin lives in 12 files. A version swap stays a multi-file edit.
Nits
runpod-flash-legacy.md:16: "next to runpod 2.x" reads oddly in the plain legacy setup block, where the project has no 2.x. Drop the comment tail or say "see Fallback from the SDK to run it next to 2.x".runpod-flash-legacy.md:29-30: double blank line.
Simplification opportunities
- Round 1's fallback de-duplication is done: SKILL.md and the migration guide now link to one procedure. Nothing new.
- Centralize the pin (R1-L10). About 18 edits now, 1 per future bump. Can be a follow-up.
Verified clean
- Migration param table against
app.pysignatures atfc4a6c7. setup-and-cli.mdignore list againstDEFAULT_IGNORES.- New
flash.yamlevidence links (main.py#L190,main.py#L718,deploy.py#L133) point at code that matches the notes. cpu_gpu_pipeline.pyfan-out: CPU jobs now spawn in parallel; GPU spawns follow as each finishes.#fallback-from-the-sdkanchors in SKILL.md and the migration guide resolve.- Gotcha 17 matches
flash.worker-api-key-every-endpoint.
Questions for the author
- Will #594 ship #623–#626 as 2.0.1? The pin still names it.
Reviewed by Claude (claude-opus-5-5) via the pr-review skill. Tokens: 24 in / 7,670 out / 652,023 cache read / 60,166 cache write = 719,883. Estimated cost: $1.75 at the rate table in the skill's sum_usage.py, 5-minute cache writes assumed. Round 2 of this PR. This is automated assistance; a human owns the final call.
Create the runpod-flash fallback environment outside the project so a deploy doesn't package it, reword the legacy install comment, and remove committed bytecode (with *.pyc ignored).
OneAsterisk
left a comment
There was a problem hiding this comment.
Claude review, round 3
Verdict: Ready after fixes. All round-2 findings are fixed; the only blocker is that the PR left draft before runpod 2.0.1 reached PyPI.
Approval gate: 0 Critical, 1 High, 1 Medium+Low → not approved: R1-H1 is open again.
Status of prior findings
| # | Finding | Severity | Status | Evidence |
|---|---|---|---|---|
| R1-H1 | runpod>=2.0.1 not on PyPI |
High | Reopened | Round 2 accepted draft status as the mitigation. The PR went back to ready for review at 2026-10-23 17:05 UTC. PyPI still tops out at 1.12.0 / 2.0.0rc2, and runpod/runpod-python#594 is still open. Merging now breaks SKILL.md:69 and the other 11 files that pin it |
| R1-L10 | pin repeated across files | Low | Not addressed | runpod>=2.0.1 still in 12 files, 23 2.0.1 mentions |
| R2-M1 | fallback venv packaged by deploy | Medium | Fixed | runpod-flash-legacy.md:43-48 uses ~/.venvs/flash-fallback; flash.yaml adds the deploy.py#L35 evidence. DEFAULT_IGNORES at fc4a6c7 does list only .venv/, venv/, env/ for venvs, so the new sentence is accurate |
| R2-L1 | committed bytecode | Low | Fixed | 5 .pyc files deleted, *.pyc in .gitignore:14. No tracked .pyc left |
| R2 nits | "next to runpod 2.x" wording, double blank line | Nit | Fixed | runpod-flash-legacy.md:16, line 29 removed |
| R1-M1…M4, R1-L1…L9, R1 nits | Fixed | Verified in round 2; files unchanged since |
Existing feedback
No human or bot comments. All round-2 threads were resolved before this push; each gets a verification reply. CI: all checks pass except nix-checks, still pending at posting; pytorch-pod-lifecycle and template-examples are skipped by path filter.
PR description vs code
| Claim | Status | Where |
|---|---|---|
"Merge after runpod 2.0.1 is on PyPI" |
✅ accurate, not yet met | PyPI, runpod/runpod-python#594 |
| Fallback isolated install | ✅ | runpod-flash-legacy.md:41-52 |
| "Review findings" table | Still lists only the 300 s and one-file items. Not a false claim |
Findings
High
- R1-H1, reopened: the PR is mergeable before its pin resolves. See the reply on the original thread. Either re-draft until 2.0.1 ships, or keep it ready and merge only after
pip index versions runpodshows 2.0.1. Once 2.0.1 is on PyPI, this round's gate passes with no other changes.
Low
- R1-L10, carried: the pin lives in 12 files. Follow-up is fine.
Nits
runpod-flash-legacy.md:46:~/.venvs/flash-fallbackis shared by every project that falls back, so a second project inherits the first one's packages.~/.venvs/flash-<project>keeps them apart.
Simplification opportunities
- Centralize the pin (R1-L10). About 18 edits now, 1 per future bump. Can be a follow-up.
Verified clean
9451b6edelta read in full (13 additions, 7 deletions, 5 binary deletions).- New
flash.yamlevidence link resolves toDEFAULT_IGNORESatdeploy.py#L35. It also lists__pycache__/and*.pyc, which deploys already dropped. - The YAML rule and the legacy guide say the same thing about where the venv goes.
.gitignore*.pyccovers the deleted files. The trackedtestdata/runpod-migrate/skipped-dirs/__pycache__/legacy.pyis a.pyfixture frommainand is unaffected.
Questions for the author
- Will #594 ship #623–#626 as 2.0.1? The pin still names it.
Reviewed by Claude (claude-opus-5-5) via the pr-review skill. Tokens: 14 in / 4,787 out / 366,273 cache read / 59,263 cache write = 430,337. Estimated cost: $1.52 at the rate table in the skill's sum_usage.py, 5-minute cache writes assumed. Round 3 of this PR. This is automated assistance; a human owns the final call.
OneAsterisk
left a comment
There was a problem hiding this comment.
Claude review, round 4
Verdict: Ready after fixes. The round-3 nit is fixed; the only blocker is still that the PR is ready for review before runpod 2.0.1 is on PyPI.
Approval gate: 0 Critical, 1 High, 1 Medium+Low → not approved: R1-H1 is still open.
Status of prior findings
| # | Finding | Severity | Status | Evidence |
|---|---|---|---|---|
| R1-H1 | runpod>=2.0.1 not on PyPI |
High | Not addressed | PR is not a draft. PyPI still tops out at 1.12.0 / 2.0.0rc2 (checked 2026-10-23). runpod/runpod-python#594 is still open. 12 files pin runpod>=2.0.1 |
| R1-L10 | pin repeated across files | Low | Not addressed | Still 12 files. Follow-up is fine |
| R3 nit | shared ~/.venvs/flash-fallback across projects |
Nit | Fixed | runpod-flash-legacy.md:46-48 now uses ~/.venvs/flash-<project> at 1d38d89 |
| R2-M1, R2-L1, R2 nits | Fixed | Verified in round 3; files unchanged since | ||
| R1-M1…M4, R1-L1…L9, R1 nits | Fixed | Verified in round 2; files unchanged since |
Existing feedback
No human or bot comments. CI: all checks pass. pytorch-pod-lifecycle and template-examples are skipped by path filter.
PR description vs code
| Claim | Status | Where |
|---|---|---|
"Merge after runpod 2.0.1 is on PyPI" |
✅ accurate, not yet met | PyPI, runpod/runpod-python#594 |
| Fallback isolated install | ✅ | runpod-flash-legacy.md:41-52 |
Findings
High
- R1-H1, not addressed: the PR is mergeable before its pin resolves. See the original thread. Re-draft until 2.0.1 ships, or merge only after
pip index versions runpodshows 2.0.1. Once it does, this round's gate passes with no other changes.
Low
- R1-L10, carried: the pin lives in 12 files.
Simplification opportunities
- Centralize the pin (R1-L10). About 18 edits now, 1 per future bump. Can be a follow-up.
Verified clean
9451b6e...1d38d89read in full: 3 lines inrunpod-flash-legacy.md.- No other file references the old
flash-fallbackpath. flash.yaml:48-49says "outside the project directory" without naming a path, so it still agrees with the guide.<project>follows the repo's existing placeholder style (<dc>infile-transfer.yaml,getting-started.md).
Questions for the author
- Will #594 ship #623–#626 as 2.0.1? The pin still names it.
Reviewed by Claude (claude-opus-5-5) via the pr-review skill. Tokens: 14 in / 3,115 out / 356,982 cache read / 54,018 cache write = 414,129. Estimated cost: $1.33 at the rate table in the skill's sum_usage.py, 5-minute cache writes assumed. Round 4 of this PR. This is automated assistance; a human owns the final call.
…the Runpod SDK (#90) * docs(volume-cache): load volume-backed models through VolumeCache on the Runpod SDK Stacked on the SDK 2.0 flash lane. VolumeCache: - Golden path 08's serve step restores the base model through VolumeCache. Live-verified: a later cold start restored 2.2 GB and loaded it in 7.2 s. - Golden path 09 keeps its model cache on local disk. - The Flash patterns add global volumes and the per-endpoint namespace in dev sessions. - model-caching.md gains a measured comparison. Qwen2.5-1.5B on fresh workers: VolumeCache 9.1 s, mount load 11 s, download 16-21 s, global-volume restore 30-55 s. * docs(volume-cache): global volumes need runpod>=2.0.1 Before 2.0.1, VolumeCache restores from a global volume copied whole files and could drop large weight shards (runpod-python #621), and the error was swallowed. The global-volume rule, model-caching.md and the Flash pattern now set the floor at 2.0.1 and mark the 2026-10-17 global-volume timings as measured before the parallel restore. * docs(volume-cache): cite SDK source instead of PRs; drop external benchmark link * docs(volume-cache): address review round 1 - Golden path 09: the template's MODEL_CACHE_DIR defaults to local disk, and the VolumeCache snippet uses the handler's own constants. - Golden path 08: the training step no longer claims the SDK serve step reuses its cache; the first SDK cold start downloads and fills the mirror. Status restored to verified, since this code is what ran. - restore-beats-mount-load names the model and says smaller models or a faster mount can change the result. * chore: remove committed bytecode from golden path 09's template
OneAsterisk
left a comment
There was a problem hiding this comment.
Claude review, round 5
Verdict: Ready after fixes. The new commit merges #90 into this branch, and its content checks out. Two blockers remain: the 2.0.1 pin, and a PR body that still describes #90 as a separate stacked PR.
Approval gate: 0 Critical, 2 High, 2 Medium+Low → not approved: R1-H1 is still open and the PR body is stale (R5-H1).
Status of prior findings
| # | Finding | Severity | Status | Evidence |
|---|---|---|---|---|
| R1-H1 | runpod>=2.0.1 not on PyPI |
High | Not addressed | PR is not a draft. PyPI still tops out at 1.12.0 / 2.0.0rc2 (checked 2026-10-23). runpod/runpod-python#594 is still open. 14 files now pin runpod>=2.0.1 |
| R1-L10 | Pin repeated across files | Low | Not addressed | 14 files, up from 12 (#90 added the pin to volume-cache.yaml and model-caching.md). A follow-up is fine |
| R3 nit, R2-, R1- (rest) | Fixed | Verified in rounds 2 to 4. Those files did not change in 1d38d89...1495679 |
Existing feedback
No human or bot comments. CI: concepts, validate, example-changes, skill-scripts-oldest-python and the PR title check pass. nix-checks was still pending at review time. Path filters skipped pytorch-pod-lifecycle and template-examples.
PR description vs code
| Claim | Status | Where |
|---|---|---|
| "VolumeCache guidance beyond the SDK port (global volumes, measured numbers, golden paths 08/09) moved to #90, stacked on this PR" | ❌ #90 merged into this branch at 1495679, so this PR now contains that guidance | patterns.md:113-121, volume-cache.yaml:128-167, model-caching.md:160-182, golden paths 08/09 |
| Stack row 10: "#90 … (stacked on #89) / Needs #89" | ❌ #90 is merged | stack table |
| Live verification: "here the base model loads from the mount as in the 2026-10-16 run" | ❌ GP08 now wraps the base-model load in VolumeCache |
08-finetune-to-serverless.md:205-206 |
"Merge after runpod 2.0.1 is on PyPI" |
✅ accurate, not yet met | PyPI, runpod/runpod-python#594 |
Findings
High
- R1-H1, not addressed: the PR can merge before its pin resolves. See the original thread.
- R5-H1: the PR body is stale after the #90 merge. Three statements above are now false. A reviewer who reads the body will not know this PR adds the global-volume rule, the measured cold-start table, or the handler.py default change in golden path 09. Fix: drop the "moved to #90" bullet and add the #90 changes to "What changes". Mark stack row 10 as merged into this PR. Update the 2026-10-17 verification row to say the serve step used
VolumeCache.
Low
- R1-L10, carried: the pin lives in 14 files.
- R5-L1: the global-volume advice in
patterns.mdomits the pre-2.0.1 caveat.patterns.md:114-116says global-volume restores "measured slower" and recommends a network volume. Those numbers predate the 2.0.1 parallel restore.model-caching.md:180-182andvolume-cache.yamlboth say to re-time on 2.0.1. Add the same caveat here (inline comment).
Nits
model-caching.md:175The "2–4 s" load for the global-volume row has no evidence involume-cache.yaml. Its evidence lists only hydrate times.api.md:144passesvolume_path=str(models.path). Thepatterns.mdexample and GP08 rely on the/runpod-volumedefault. Both work; pick one form.
Simplification opportunities
- Centralize the pin (R1-L10). This saves about 20 edits on each future bump. It can be a follow-up.
Verified clean
- Read
1d38d89...1495679in full (9 files, +134/-31). - Anchors
#loading-ml-models,#measured-cold-startsand#network-volume--load-from-local-disk-with-volumecacheresolve. Thesee:IDsvolume-cache.mirror-sizingandflash.dev-sessionexist. - GP08 serve step:
VolumeCachedefaultsvolume_pathto/runpod-volume(rp_volume_cache.py:77at v1.12.0), which matches the mount.HF_HOMEnow points at local disk, so the mirror has something to copy. - GP09: the README snippet runs at import in pod mode too. There
VolumeCachedisables itself because noRUNPOD_ENDPOINT_IDis set and/runpod-volumeis absent (rp_volume_cache.py:129-130). The template's unpinnedrunpodresolves to 1.12.0, which shipsVolumeCache, so the>=1.12.0claim holds. - The namespace rule matches the source:
namespace or os.environ.get("RUNPOD_ENDPOINT_ID")(rp_volume_cache.py:87). - The 600 MB/s figure matches 3.1 GB / 5.2 s. The table totals match the yaml evidence.
- The golden-paths index row 08 (✅ SDK) agrees with GP08's status paragraph. No committed bytecode remains outside
testdata/.
Questions for the author
- Will #594 ship #623–#626 as 2.0.1? The pin still names it.
Reviewed by Claude (claude-opus-5-5) via the pr-review skill. Tokens: 14 in / 6,331 out / 354,091 cache read / 61,564 cache write = 422,000. Estimated cost: $1.64 at the rate table in the skill's sum_usage.py, assuming 5-minute cache writes. Round 5 of this PR. This is automated assistance; a human owns the final call.
Global-volume advice in patterns.md says its timings predate 2.0.1's parallel restore; api.md shows VolumeCache's /runpod-volume default and when to pass volume_path; the global-volume load time is ~4 s, with the hydrate-plus-load totals in the evidence.
OneAsterisk
left a comment
There was a problem hiding this comment.
Claude review, round 6
Verdict: Ready after fixes. Every round-5 fix checks out, but the PR can still merge before runpod 2.0.1 exists.
Approval gate: 0 Critical, 1 High, 2 Medium+Low → not approved: R1-H1 is still open.
Status of prior findings
| # | Finding | Severity | Status | Evidence |
|---|---|---|---|---|
| R1-H1 | runpod>=2.0.1 not on PyPI |
High | Not addressed | The PR is ready for review. PyPI still tops out at 1.12.0 / 2.0.0rc2, and runpod/runpod-python#594 is open (checked 2026-10-23) |
| R5-H1 | PR body stale after the #90 merge | High | Fixed | The "moved to #90" bullet is gone. Stack row 10 says merged into #89. "What changes" lists the VolumeCache work. The 2026-10-17 row names VolumeCache |
| R5-L1 | Global-volume advice omits the pre-2.0.1 caveat | Low | Fixed | patterns.md:114-117, 81c2d69 |
| R5 nit | "2–4 s" global-volume load had no evidence | Nit | Fixed | volume-cache.yaml:153 now records "hydrate plus model load 30-55 s"; subtracting the 26.2/51.4 s hydrates gives about 4 s, matching model-caching.md:175 |
| R5 nit | api.md vs patterns.md disagree on volume_path |
Nit | Fixed, with a new gap (R6-L1) | api.md:144-147 now states the default |
| R1-L10 | Pin repeated across files | Low | Not addressed | Still 14 files. A follow-up is fine |
| R1-, R2-, R3 nit (rest) | Fixed | Verified in rounds 2 to 5. Those files did not change in 1495679...81c2d69 |
Existing feedback
No human or bot comments. CI: concepts, validate, example-changes, skill-scripts-oldest-python and the PR title check pass. nix-checks is still pending. Path filters skipped pytorch-pod-lifecycle and template-examples.
PR description vs code
| Claim | Status | Where |
|---|---|---|
| Stack row 10: #90 merged into #89 | ✅ | 1495679 |
| VolumeCache bullets under "What changes" | ✅ | patterns.md, volume-cache.yaml, model-caching.md, GP08/GP09 |
2026-10-17 row: base model through VolumeCache |
✅ | 08-finetune-to-serverless.md |
"Merge after runpod 2.0.1 is on PyPI" |
✅ accurate, not yet met | PyPI, runpod/runpod-python#594 |
Findings
High
- R1-H1, not addressed: the PR can merge before its pin resolves. See the original thread.
Low
- R1-L10, carried: the pin lives in 14 files.
- R6-L1: the task advice in
api.mdproduces a silent no-op.api.md:144-147says to passvolume_path=str(models.path)"as on a task". Tasks run on a pod (app.py:154: "declare ephemeral pod compute"), soRUNPOD_ENDPOINT_IDis unset. Without it the namespace is empty andavailableis False (rp_volume_cache.py:119,167at fc4a6c7), so hydrate and sync do nothing. The repo's own rulevolume-cache.silent-without-namespacesays this. Fix: also passnamespace=on a task (inline suggestion).
Simplification opportunities
- Centralize the pin (R1-L10). This saves about 20 edits on each future bump. It can be a follow-up.
Verified clean
- Read
1495679...81c2d69in full (4 files, +9/-7). - The
patterns.mdcaveat matchesmodel-caching.md:180-182and the parallel-restore evidence involume-cache.yaml. api.md:volume_pathdefaults to/runpod-volume(rp_volume_cache.py:105at fc4a6c7), and tasks mount at distinct paths (api.md:139,flash.volume-mounts), so the default does not fit a task.- The
#loading-ml-modelsand#measured-cold-startsanchors still resolve.
Questions for the author
- Will #594 ship #623–#626 as 2.0.1? The pin still names it.
Reviewed by Claude (claude-opus-5-5) via the pr-review skill. Tokens: 24 in / 5,197 out / 672,325 cache read / 58,854 cache write = 736,400. Estimated cost: $1.61 at the rate table in the skill's sum_usage.py, assuming 5-minute cache writes. Round 6 of this PR. This is automated assistance; a human owns the final call.
OneAsterisk
left a comment
There was a problem hiding this comment.
Claude review, round 7
Verdict: Ready after fixes. The R6-L1 fix checks out, but the PR can still merge before runpod 2.0.1 exists.
Approval gate: 0 Critical, 1 High, 1 Medium+Low → not approved: R1-H1 is still open.
Status of prior findings
| # | Finding | Severity | Status | Evidence |
|---|---|---|---|---|
| R1-H1 | runpod>=2.0.1 not on PyPI |
High | Not addressed | The PR is ready for review. PyPI still tops out at 1.12.0 / 2.0.0rc2, and runpod/runpod-python#594 is open (checked 2026-10-23) |
| R6-L1 | Task advice in api.md is a silent no-op without namespace= |
Low | Fixed | api.md:146-148 now says to pass volume_path=str(models.path) and a namespace= on a task, and why, 4dd848e |
| R1-L10 | Pin repeated across files | Low | Not addressed | Still 14 files. A follow-up is fine |
| R1 to R5 (rest) | Fixed | Verified in rounds 2 to 6. Those files did not change in 81c2d69...4dd848e |
Existing feedback
No human or bot comments. CI: concepts, validate, example-changes, nix-checks, skill-scripts-oldest-python and the PR title check pass. Path filters skipped pytorch-pod-lifecycle and template-examples.
PR description vs code
| Claim | Status | Where |
|---|---|---|
| VolumeCache bullets under "What changes" | ✅ | unchanged since round 6 |
"Merge after runpod 2.0.1 is on PyPI" |
✅ accurate, not yet met | PyPI, runpod/runpod-python#594 |
Findings
High
- R1-H1, not addressed: the PR can merge before its pin resolves. See the original thread.
Low
- R1-L10, carried: the pin lives in 14 files.
No new findings.
Simplification opportunities
- Centralize the pin (R1-L10). This saves about 20 edits on each future bump. It can be a follow-up.
Verified clean
- Read
81c2d69...4dd848ein full (1 file, +3/-2). - The new
api.mdwording matchesvolume-cache.silent-without-namespace(volume-cache.yaml:93-99) and the fixed-namespace advice inpatterns.md:134-136. nix-checks, pending in round 6, now passes.
Questions for the author
- Will #594 ship #623–#626 as 2.0.1? The pin still names it.
Reviewed by Claude (claude-opus-5-5) via the pr-review skill. Tokens: 12 in / 2,904 out / 288,088 cache read / 49,312 cache write = 340,316. Estimated cost: $1.20 at the rate table in the skill's sum_usage.py, assuming 5-minute cache writes. Round 7 of this PR. This is automated assistance; a human owns the final call.
OneAsterisk
left a comment
There was a problem hiding this comment.
Claude review, round 8
Verdict: Ready after fixes. The new head is a clean merge from main, and the flash docs did not change, but the PR can still merge before runpod 2.0.1 exists.
Approval gate: 0 Critical, 1 High, 1 Medium+Low → not approved: R1-H1 is still open.
Status of prior findings
| # | Finding | Severity | Status | Evidence |
|---|---|---|---|---|
| R1-H1 | runpod>=2.0.1 not on PyPI |
High | Not addressed | The PR is ready for review. PyPI still tops out at 1.12.0 / 2.0.0rc2, and runpod/runpod-python#594 is open (checked 2026-10-26) |
| R1-L10 | Pin repeated across files | Low | Not addressed | runpod>=2.0.1 appears in 13 files. A follow-up is fine |
| R1 to R7 (rest) | Fixed | Verified in rounds 2 to 7. No PR file changed in 4dd848e...8766329 |
Existing feedback
No human or bot comments. CI: concepts, validate, example-changes, skill-scripts-oldest-python and the PR title check pass on the merge commit. nix-checks is still running (started 22:15 UTC). Path filters skipped pytorch-pod-lifecycle and template-examples.
PR description vs code
| Claim | Status | Where |
|---|---|---|
"Merge after runpod 2.0.1 is on PyPI" |
✅ accurate, not yet met | PyPI, runpod/runpod-python#594 |
| Rest of the body | ✅ | Unchanged since round 7; no PR file changed |
Findings
High
- R1-H1, not addressed: the PR can merge before its pin resolves. See the original thread.
Low
- R1-L10, carried: the pin lives in 13 files.
No new findings.
Simplification opportunities
- Centralize the pin (R1-L10). This saves about 20 edits on each future bump. It can be a follow-up.
Verified clean
8766329merges890604f(main, #98 and #99) into4dd848e.git show --remerge-diffis empty, so the merge resolved no conflicts.- The 9 files from
main(pod, container-disk and storage docs, two evals, GP25) do not overlap the PR's 47 files and do not mention flash,VolumeCacheorrp flash. - The new
see:IDs frommain(pod-volume-disk.network-filesystem-backed,container-disk.*) resolve, and theconceptscheck passes on the merge commit.
Questions for the author
- Will #594 ship #623–#626 as 2.0.1? The pin still names it.
Reviewed by Claude (claude-opus-5-5) via the pr-review skill. Tokens: 16 in / 3,371 out / 451,738 cache read / 59,913 cache write = 515,038, plus this posting turn. Estimated cost: $1.48 at the rate table in the skill's sum_usage.py, assuming 5-minute cache writes. Round 8 of this PR. This is automated assistance; a human owns the final call.
Flash → SDK 2.0 fix stack
Status as of 2026-10-23. 1–5 are merged, and 10 is merged into 9. Hover a link for its status.
mainpeft/accelerateno longer bundledrp flash devdeletes its endpoints when stopped by a signalvol.pathworks on deployed workersrunpod2.0.1 with 2–5 (release PR #594). 2.0.0rc2 (2026-10-20) predates themFlash ships in
runpod2.0 as SDK apps (runpod.App,rp flash), andrunpod-flashis deprecated on October 29, 2026. Until this PR, the plugin taught onlyrunpod-flash.What changes
flashskill rewritten SDK-first. It checks which SDK a project is on, and new references cover migrating fromrunpod-flashand maintaining legacy projects.flash/examples/: five single-file apps, all passing live.flashconcept rules rewritten with public-doc and live evidence; the rules that cite them are updated.rp login/rp flash.runpod-flashwhen the SDK path fails on an SDK bug: how to tell it from a code bug, where to look for a fix (runpod-python CHANGELOG andrunpod/appshistory, runpod-flash history), and an isolated install (uv tool install runpod-flash --with "runpod<2", live-checked next torunpod2.x). The migration guide keeps the old endpoints until the new ones pass. New ruleflash.legacy-fallbackand evalsdk-failure-fallback.VolumeCacheand loads it from local disk; the LoRA adapter is still read from the volume.MODEL_CACHE_DIRon container disk (/app/whisper-cache), and the README wraps the load inVolumeCache.patterns.md,api.mdand SKILL gotcha 8 load weights throughVolumeCache, coverrunpod.GlobalVolumeand the per-endpoint mirrornamespace.model-caching.mdgains a global-volume bullet and a Measured cold starts table.volume-cacheconcept: new rulesrestore-beats-mount-load,global-volume(needsrunpod>=2.0.1) andnamespace-per-endpoint.No SDK workarounds left. With 2.0.1:
peft/acceleratestays out of the bundle, so those are plaindependencies.vol.pathworks on deployed workers.killcleans up a background dev session.Still open: the API-key fix (runpod/runpod-python#628, then #641) was closed unmerged, so deploy and dev add the account key to every endpoint. The docs now say that (
flash.worker-api-key-every-endpoint).Remaining gotchas are behavior, not bugs: whole-number floats arrive as ints, and dev sessions run the runtime image's own
runpod.Live verification
2026-10-16,
runpod2.0.0rc1:rp flash dev --once2026-10-17, a local
runpodbuild with #623–#628 merged (1509 SDK tests pass):peft+accelerateas plain dependencies,vol.pathfor the adapter, base model throughVolumeCachetorch 2.9.1+cu128, generated text; the first cold start downloaded the base model in 10.3 s, a later cold start restored 2.2 GB throughVolumeCacheand loaded it in 7.2 sAll test endpoints and volumes were deleted. Repo checks: ontology validate (0 errors), check:guides, links, branding, frontmatter, versions, marketplace, CLI absence claims, migrate checks.
How we tested and compared
Workarounds vs. no workarounds. Each SDK workaround the rc1 docs carried was first reproduced on rc1:
pip install --no-depsat runtime forpeft(rc1 crash-looped withlibcudart.so.13)/runpod-volumeinstead ofvol.path(rc1 raised "not mounted")kill(rc1 left the endpoint running)The same golden paths and examples were then re-run on a local build with #623–#628, with the workaround removed. The doc changed only where that run passed.
Docs vs. SDK source. Every SDK claim in the diff was checked against the SDK source. Concept rules cite the public docs or the SDK source line.
Review findings
.remote()has no timeout. On a queue, it stops waiting after 300 s (DEFAULT_TIMEOUT_SECONDS) while the job keeps runningapi.md,flash.yaml(flash.client-limits, with SDK evidence) and golden path 03-B now say 300 s on a queue and point to.spawn()+job.result(timeout=...)for longer calls. Task calls have no client timeout, so the claim is scoped to queues.flash.same-module-in-dev-and-deployscope the one-file rule to dev sessions, withdeploy.pyevidence.