Skip to content

feat: one command to prepare and serve - #20

Merged
youssef62 merged 4 commits into
mainfrom
api-refactor
Aug 17, 2026
Merged

feat: one command to prepare and serve#20
youssef62 merged 4 commits into
mainfrom
api-refactor

Conversation

@youssef62

@youssef62 youssef62 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

What

servekit prepare is gone. servekit launch does both steps now:

servekit launch --servekit-artifact-path /scratch/llama-tp4   -- python -m sglang.launch_server --model-path /models/llama --tp 4

--servekit-artifact-path is where servekit keeps the presharded copy. If
there is nothing prepared there, launch prepares it first and then serves.
--model-path always names the real model, and --load-format sharded_state
is added for you.

Use --only-prepare to run just the prepare step, for building the artifact
in its own job.

Mismatches are warnings now

Before, a command that did not fit the checkpoint made launch exit 2. Now it
says which setting disagrees and runs the plain engine command instead:

[SERVEKIT] warning: /scratch/llama-tp4 does not match this command:
[SERVEKIT]   tp_size: the checkpoint is sharded for 4, the command asks for 8
[SERVEKIT] falling back to the default loader (slower cold start).

A slower start beats a failed job. Same when the artifact path cannot be
written. With --only-prepare a mismatch rebuilds the artifact instead.

One new check: an artifact prepared from a different model is a mismatch. That
is easy to hit now that the artifact dir is a separate argument.

youssef62 and others added 2 commits August 17, 2026 11:40
`servekit prepare` is gone as a subcommand. `servekit launch` now takes
`--servekit-artifact-path <dir>`, prepares the checkpoint there if it is
not prepared yet, and serves it. `--model-path` always names the real
model, and `--load-format sharded_state` is added automatically.

    servekit launch --servekit-artifact-path /scratch/llama-tp4 \
      -- python -m sglang.launch_server --model-path /models/llama --tp 4

`--only-prepare` does the prepare step alone, for building the artifact
in its own job.

An artifact that does not fit the command no longer fails the run: it
names the setting that disagrees and falls back to the engine's own
loader. Same for an artifact path that cannot be written. A manifest
prepared from a different model now counts as a mismatch too.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both jobs now run the same command; the only difference is whether the
artifact directory already holds a prepared checkpoint. So
correctness-apertus8b.sbatch takes a FRESH switch that points the artifact
at an empty scratch dir, and prepare-serve-apertus8b.sbatch goes away.

sbatch_wait takes an env overlay, so FRESH reaches the job without being
set on os.environ where it would leak into the other e2e module's jobs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@youssef62 youssef62 changed the title One command to prepare and serve feat: one command to prepare and serve Aug 17, 2026
youssef62 and others added 2 commits August 17, 2026 13:42
Preparing Qwen3-Coder-30B never finished: the MoE loader faults pages out
of an mmap'd safetensors file, which on Lustre becomes random reads. It sat
in _load_w13 for 30 minutes against ~2 minutes of streaming reads, so the
sharding run now sets weight_loader_disable_mmap. The slow-path fallback in
launch gets the same flag, since that is the other place servekit hands the
original checkpoint to the engine. The fast path keeps mmap, where it reads
the staged copy out of tmpfs for free.

Also raise the sharding run's distributed timeout. One prepare died when
ranks that finished writing waited past torch's 600s default for a rank
that had not. That run turned out to be an unusually slow window rather
than a real limit, so this is a guard: crossing that boundary throws away
a load that already succeeded.

Drop the "JIT caches will be built in /tmp/..." line, which read as though
the caches were not kept with the checkpoint.

Verified on Clariden: Apertus-8B TP4 and TP2/PP2, Llama-70B TP4, and
Qwen3-Coder-30B TP4 all prepare from empty and pass servekit verify.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GLM-4.7 gets OOM-killed with the flag on, reproducibly: OUT_OF_MEMORY at
1:39 and 1:37 across two runs, one shard into the load, where the same
model on the same nodes loads fine with mmap. Disabling mmap reads each
shard into anonymous memory the kernel cannot evict, and the multi-thread
loader holds several at once.

Size does not predict it, so a threshold would not be safe either:
Qwen3-235B carries 219G per node with the flag on and loads in 87s, while
GLM-4.7 died carrying 167G per node.

Preparing a checkpoint that hangs on mmap is still fixable by passing
--weight-loader-disable-mmap in the engine command, which the sharding run
already forwards. Servekit no longer chooses it for you.

The distributed timeout stays: it guards a real cliff and costs nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@youssef62
youssef62 merged commit 9f0a392 into main Aug 17, 2026
@youssef62
youssef62 deleted the api-refactor branch August 17, 2026 12:35
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.

1 participant