Repository navigation
Conversation
…es (ashhart#2761) `tensorfold info MODEL [--context N] [--parallel N|auto]` prints the startup budget (weights, every stream's KV and state, the prompt scratch) and whether it fits this Mac's Metal working set beside the 8 GiB margin. The charge comes from native/qwen27_reserve.zig, which serve now calls for its fit and prompt rows, so the two cannot drift. hub.modelType returns its string in the caller's allocator instead of a parse it has freed.
Owner
|
Hi @cshintov, thanks. Tying
Next step on our side: the M5 run of
|
Owner
|
Follow-up on our side, at your head 6808133:
It's queued to land. Softening the
|
This branch has not been deployed
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.
What this changes
On Metal,
tensorfold infoprinted a context-free "memory floor" (weights plus 2 GiB) for Qwen3.8-27B.tensorfold info MODEL [--context N] [--parallel N|auto]now prints the chargeservemakes at startup, computed by the same code, and whether it fits this Mac.servehas no memory admission, so a 262k-context start on a swapping Mac reserves 67 GB in seconds and the kernel watchdog panics #2761 (item 1; the startup warning is fix(qwen27): warn when Metal startup exceeds available memory #2886).atc overlap --json: not run (atcisn't installed here). By hand, open PRs that touch the same files: fix(qwen27): warn when Metal startup exceeds available memory #2886 adds lines right after thefit_promptlines this moves inqwen27_served.zigand keeps working againstreserve.fit(it still returns aprompt_memory.Fit); train 1113142824: #2921 (CI only) #3229, train 1113140943: #2868 #2875 #2723 #2902 #2903 #2906 #2861 #2570 (CI only) #3228, qwen27 metal: M5 takes TF_QWEN27_METAL_KV_PAGES; a paged prompt chunk finds its two pages once #3180, metal: presence and frequency penalties on Flash Next and Qwen3.8-27B, each row over the reply and its own path #3145, environment: Metal Qwen paging, slot resume and slide checks refused by name (#2370) #3018 and qwen27 served: the reply-end keep test names its history, and a step runs it #3012 touch other parts ofqwen27_served.zig; Nemotron on Metal: warm turns, so a long follow-up resumes past the previous prompt #3190, cli: tensorfold device says what this machine runs, saved in ~/.tensorfold/device.json #3107, lanes: Nemotron plain streams share one exact Metal round (+20% at 2 streams, +77% at 4) #3005 and llama on Metal: Qwen2 checkpoints, Bimo-7B-CyberAgent's bf16 release with its q, k and v biases and YaRN at HF's rounding points #2890 touch other parts ofmetal.zig, and cli: tensorfold device says what this machine runs, saved in ~/.tensorfold/device.json #3107 a different command incli.zig.Per file:
cli/info.zig,cli/cli.zig: the flags read asservereads them (--contextdefaults to 32,768, 1 to 262,144 and withinmax_position_embeddings;--paralleldefaults toauto, 8 that shrink to what fits, and a number asks for exactly that many). For a checkpoint the Metal engine opens on the 27B-class host, two lines replace the floor:The second line also says when
servewould start fewer streams, or refuse. A checkpoint the engine can't price (a shape the attention plan rejects, for example) printsstartup budget: not priced (TargetAttentionShape)and keeps the floor.native/qwen27_reserve.zig(new): the fitservecharges (fit), the prompt rows it takes (rows,requested), the working-set cap, andbudget, which prices a checkpoint unloaded.qwen27_served.zigcallsfit,rows,requestedandcapfrom here instead of building its own.native/metal.zig: the "opens on the 27B host" test and the context rule becomeownsQwen27andqwen27Context, used byopenand by the newqwen27Budget.cli/hub.zig:modelTypereturned a slice into the JSON parse it had just freed; it now copies it into the caller's allocator (every caller passes an arena).Design
Choice:
infocallsFit.costthrough the samefitandrowsthatservecalls. One input is a stand-in: unloaded, the model's bytes are its weight files plus the frame the deferred load allocates, whereservereadsdevice.allocated(). Those bytes decide only the room the fit is checked against, never the charge itself.Alternatives considered:
info(layers x context x KV width): the drift Metal:servehas no memory admission, so a 262k-context start on a swapping Mac reserves 67 GB in seconds and the kernel watchdog panics #2761 warns about, and it misses the GDN state, prompt scratch and tap planes thatrunnerBytescounts.infoand readdevice.allocated(): exact, but it costs the weights' memory and seconds, which defeats a pre-start check on a Mac already short of memory.Deferred:
--drafter(the ring and tap planes already go throughfit;infowould need the drafter's config and size) and images (the tower loads before the slots). The line says "no drafter or images".Checks on this head
getenvs that moved now read throughplatform/environment.zig).zig build test-cli40 pass, 15 skip, 0 fail. New: "info --context and --parallel parse as serve reads them" and "info prices a Qwen3.8-27B start from serve's charge" (8,192 against 262,144 tokens, 1, 2 and auto streams, a capped working set that fits no stream, a context past 262,144, a shape the engine refuses). Both fail on main. Withhub.modelTypeput back as on main, the pricing test fails too: the secondinfoin the process reads a freedmodel_type.zig build compile-metal-residency-hostbuilds;zig build native -Dcpu=apple_m1builds.budgetreads, the same onesservereads.Receipt
Environment: this change on main c34ff56 (rebased since onto aaac299 with no conflict outside CHANGELOG; tests above rerun on the new head), Zig 0.17.0, Xcode Metal toolchain, Apple M4 Pro, 64 GB (51.8 GiB Metal working set), macOS 26.5. Checkpoint TensorFold/Qwen3.8-27B-MLX-4bit @ 22d8d538154e0e5b6f8dcb1fcc74a60a0798104c.
infoagainst real starts.serve ... --parallel 1 --context N --prompt-cache-gib 0: itsqwen27: prompt capacity=... reserve=...line, andtensorfold:process_footprint_bytesfrom/metricsafter one 4-token greedy request:The step from 8,192 to 32,768 tokens is 1.50 GiB in
info, in the logged reserve and in the footprint. The 0.38 GiB gap doesn't move with the context, so it sits in the fixed stand-in, not in the charge, and errs high. At 262,144 tokensserveexits: "--parallel 1 needs 33.9 GiB for its streams and 512-row prompt scratch at a 262144-token context; 29.5 GiB remains beside the weights and an 8 GiB margin".Main against branch,
serve ... --parallel 1 --context 8192: the same start on both,qwen27: prompt capacity=512 rows, startup stream and scratch reserve=4636573696 bytesandQwen3.8-27B: 1 stream of 8192 tokens; footprint after one request 20,527,967,824 B on main and 20,526,722,616 B on the branch.Exactness, decode and prompt speed: n/a. Nothing after startup changes:
serve's fit and rows are the same expressions, moved.New switch:
info --context Nand--parallel N|auto, defaults 32,768 and auto, asserve.Licence of any new weights: n/a.