Conversation
ae3a86c to
edaab22
Compare
|
@vhain Nice work! |
merrymercy
left a comment
There was a problem hiding this comment.
Thanks for your contributions! The code quality is very high and it is well tested. Great work! I only have few minor style comments.
|
In the future, we plan to wrap all the logits processing and sampling into the Cuda graph as well. |
|
|
@Ying1123 @zhyncs I'm still pretty new to this ground (started playing with LLM ~ month ago, started using |
|
Yes, do not worry about it for now. We will refactor and start moving the sampling code to be within the CUDA graph. We will let you know later and ask for your help if needed. |
|
We found that presence_penalty has a great influence on the speed of decode. This can be reproduced in version 0.3.0, but does not occur in version 0.2.13. |
|
@hnyls2002 Is this related to how the cuda graph is triggered? |
|
@Xu-Chen Recently, we did some modifications to how the cuda graph is enabled. In 0.3.0, if you set penalty or regex, cuda graph will be disabled. This is a bug and we will fix it soon. |
|
@vhain @Xu-Chen I believe the performance slowdown problem will be fixed in #1392. With llama3.1-8b on 1 A100, the decoding speed is 77 tokens per sec the same as without presence penalty, but on main the speed is 71 tokens per sec. On 4 x A100, the decoding speed is 129 tokens per sec, while without presence penalty the speed is 134 tokens per sec, but on main the speed is 58 tokens per sec. |
|
@vhain @Xu-Chen @merrymercy
The second phase was fully overlapped by (this calculation can be executed parallel with model forward)Also, the first phase can be overlapped, I have made some tries, but it failed. What I thought was to make the cumulate a lazy operation, only being done when batch size changes or before applying. This can save more time and make the inference with penalties as fast as in normal cases. If you are interested in this, you are welcome to contribute to this optimization. |
Update test_npu_llava_onevision_qwen2_7b_ov.py
…he silent hop Boot 2 of window-flip-0828 wedged silently for 10+ minutes: PP0 and PP1 blocked in gloo waitSend under _pp_commit_comm_work's naked p2p_work.work.wait() (PP1 via _pp_commit_pending_req_work), PP2 in _do_recv -- a closed three-arc cycle on a group whose own timeout is two hours. The sgl-project#753 comment in this file already described the exact shape (boot v7pp9); the ordering was fixed then, the wait stayed naked. The bound routes through the sgl-project#630/sgl-project#829 canon (hicache_collective.bounded_wait -> ParkedWait): the unbounded wait() parks on a thread and the deadline is on the JOIN. Deliberate deviation from the order's 'pass the deadline into work.wait(timeout)': sgl-project#829 retracted that design in this tree -- an expired timed Work.wait closes the gloo pair, and hicache_collective.py names _pp_commit_comm_work as a measured victim (34 of 262 boot logs). Budget 120 s (SGLANG_PP_RING_COMMIT_BUDGET_S; <= 0 = documented escape hatch, byte-for-byte pre-sgl-project#973), reasoned against the canon's constants: 12.6x the longest healthy cutover, 4x the sgl-project#789 budget, 5x under the HiCache bound, 60x under the group timeout. On expiry: RingCommitTimeout with a sgl-project#650-style peer statement naming the silent hop; transport failure is NOT converted (sgl-project#734 stays distinguishable). Helpers are module-level, not methods -- the method form broke ~12 one-method-at-a-time stand-in holders (measured: 796 5->2, 801 14->3), recorded in a code comment. Wait-site audit: :5253 bounded-now; :3270 bounded by delegation (proven by test); _do_recv/:7592 and :5545 bounded-already via the sgl-project#789 gate; parallel_state.py recv_object stays unbounded and is NAMED as its own posten (needs the resumable PpChainReceiver treatment, not a terminal bound mid-protocol). Tests: test_ring_commit_bounded_973.py, 5 arms on real 3-process gloo -- pre-sgl-project#973 naked commit HANGS (distinguished from raised via fsynced progress marker), bounded commit raises within budget with the peer statement, healthy paired traffic unchanged, escape-hatch mutant hangs again (can-fail), :3270 reachability arm. Gates: BEFORE == AFTER byte-identical on 796(5)/801(14)/797(31)/630(5+14)/829(7) plus an 18-module sibling sweep; extraction count probe OK on every run. ruff/codespell: 0 new findings.
void-relay launched-verdict) into merge/flip-window-0828 Root fix for boot 2's ring wedge: pp_void_relay_launched_verdict stops a retraction-less zero-offer void from travelling to a never-launched rank (unmatched -> stash -> positional mis-consume by the next healthy generation -> one rank's live batch emptied -> ring one message short). Legacy byte-identical when the launched chain is absent. Terrain overlap with sgl-project#973/sgl-project#974 in scheduler_pp_mixin.py reviewed at merge.
…ed chain The merge gate on b3a2a59 surfaced the same interface drift sgl-project#978's own branch repaired once in test_pp_retracted_pass_void_797.py, in two more modules its neighbour set did not include: the event loop now passes launched_chain= to _pp_send_admission_decision (798's recorder stub: TypeError unexpected keyword) and calls _pp_note_launched_chain (631's _Rank: AttributeError -- it takes shipping methods unbound one name at a time). Repairs follow the in-file conventions: 798's recorder accepts and ignores the kwarg exactly as it ignores expects_output (the 797 repair verbatim); 631's _Rank takes the SHIPPING _pp_note_launched_chain unbound like its twelve neighbours -- its own docstring guarantees stand-in tolerance (sgl-project#787). No assertion touched. Solo re-runs: 631 6 passed, 798 7 passed; merge-tip failure set now byte-identical to baseline (the two known test_collective_family_siblings_610 assertions). Named for the sgl-project#978 desk strand, not fixed here: _pp_note_launched_chain as a self.-method repeats the one-name-at-a-time holder-binding class that sgl-project#973 and sgl-project#974 each just converted to module-level functions after measured breakage; third module falls to it here.
… Prefetch-Verdikt TOLD auf der Request-Leitung Befund (Boot xsn116, 2026-09-15 17:32:17, rid e10588ca, zweite Anfrage mit identischem Praefix, D hatte ihn durchgeschrieben): jeder P-Rang registriert seinen HiCache-Storage-Prefetch, keiner wartet darauf (sgl-project#973 PP0 PREFETCH WAIT DISARMED / #969Z), der spaeter fertige Host-Treffer wird als sgl-project#1245 'undistributable' verworfen, damit die Raenge gleich bleiben -- P prefillt einen im Store byte-vollstaendigen Praefix neu (STORE WITNESS state=unprobed loaded=0, 'sgl-project#928 anchor REFUSING resume ... re-prefilling'). D leg 2 liest denselben Store korrekt (cached_tokens=4314/4316), weil der TP-Pfad wartet (Policy timeout) und MIN-reduziert. Fix: der Traeger ist die Request-Leitung, die es schon gibt (recv_reqs wird je Pass PP0->PP1->PP2 gepickelt weitergereicht; sgl-project#1268 fix 1c faehrt dort schon Weg2IdleVoteReq). Protokoll je rid: 1. Intake: PP0 registriert wie bisher und haelt; Folgestufe registriert NICHTS ('declined:weg2_held', neuer sgl-project#915-Partitionsterm). 2. PP0 vor dem Forward: fuer jeden gehaltenen rid mit terminiertem Prefetch (check_prefetch_progress, kollektivfrei bei tp_size 1) wird die geladene Zahl ohne Pop gelesen, als told gespeichert und als Weg2StoreTold(rid, told) auf die Leitung gehaengt. PP0 admittet nur, was es auf die Leitung gelegt hat. 3. Folgestufe nach dem Forward, vor dem Dispatch: nimmt die Objekte aus der Liste, speichert told, registriert den Prefetch fuer EXAKT told Token (_prefetch_kvcache(limit_tokens=told)) -- gleiche Seiten, gleiche Laenge, gleicher Store: Host-Baum und Load-Back-Extent sind inhaltlich uniform, keine Praefix-Truncation an einem Mamba-Anker noetig. 4. Admission auf jedem Rang: ohne told -> Skip 'weg2_store_told_pending'; mit told -> bounded Warten auf den eigenen Read, Pop, und benannte Verweigerung Weg2StoreToldMismatch bei own != told (Raenge nie uneins). Der sgl-project#1245-Drop bleibt fuer die traegerlose Form ohne told; mit told ist der Extent verteilbar. Arm nur bei pp_size>1, tp_size==1, Storage an, kein Zeilentraeger; Kill-Switch SGLANG_WEG2_STORE_TOLD=0. pp_size<=1 (Gruppe D) unveraendert. Tests: test_weg2_store_told_1400.py 12 gruen; Mutant (Admission ohne Verdikt + Mismatch-Refusal aus) 3 rot. 16 Test-Dateien der beruehrten Symbole: 34 rot vor und nach der Aenderung identisch (Sockel: Doubles ohne ps / _pp_post_send / _pp_send_admission_decision), 0 neu. Provider-Smoke 19/19. Metall-Abnahme steht aus (arm_xsn117): zweite Anfrage gleicher Praefix -> P leg 1 cached_tokens>0 und 0x 'sgl-project#928 anchor REFUSING'.
…tore read: partial hit = admit Boot xsn121 (991e1ea), rid 06089842 (Q1 prefix + 6.8k appendix): the told carrier now lands (PP0 told=4095, PP1 ABSORBED/WAITED, 'sgl-project#988 LOADBACK prefix moved to 4095', no mismatch), but PP0 then went through the sgl-project#1324 'STORE READ INCOMPLETE delivered=4095 deliverable=11126 shortfall=7031' arm (A12.2 store_prefix_short deferral), re-issued the 7031-token remainder every pass ('sgl-project#1035 PREFETCH DROPPED host anchor pool exhausted avail=0 size=4', 'sgl-project#915 PREFETCH REFUSED alloc_failed_post_vote'), sat 'ADMISSION-WEDGE: 1 queued, 0 running' for 120 s and died on 'sgl-project#973 RING COMMIT TIMEOUT' -- while PP1 had admitted (extent 4095..8191). The arm was built for the single-stage CONSUMER (group D, leg 2: P's write-through still in flight, boot weg2sn6s). On a PP prefill group the store has no producer to wait for -- the group itself prefills the rest -- so a read that terminated short is a partial hit to admit. `_weg2_note_store_shortfall` returns None on `ps.pp_size > 1`; the single-stage form is byte-identical (no ps on the harness doubles -> 1). Tests: test_weg2_store_consistency_1324 (+1: PP group admits the partial hit) + test_weg2_store_told_1400: 39 passed.
Thank you for your contribution, we really appreciate it. The following instructions will help improve your pull request and make it easier to receive feedback. If there are any items you don't understand, don't worry. Just submit the pull request and ask the maintainers for help.
Motivation
Penalties are defined in SamplingParams, and the tensors being created during batch execution, but not yet implemented.
Also we can cut-down some milliseconds in ITL, and some VRAM usage, by not creating those unnecessary tensors.
Modification
sampling_parameters, and added them to OpenAI protocol in same name as appeared on vllm for compatibility:stop_token_ids: similar tostop, but token IDs instead ofstr. This could be useful when used withmin_new_tokens.repetition_penaltymin_new_tokenssampling_parametersare documented.sglang.bench_servingto accept additional--request-bodyto specifysampling_paramsif desired.Benchmark
Benchmarks were ran on single NVIDIA H100 SXM5
Baeline calculated on dc9d06d:
Calculated on this PR's branch (without any penalizers):
Additional benchmarks can be found in the updated sampling_params.md
Notes to Reviewers
This is my very first time writing Python code, and thus working with PyTorch (my industry backgrounds are primarily Golang, Rust, Java, Nodejs, ...). So please feel to add any comments if something looks off or inefficient.
Checklist
pre-commit run --all-filesor other linting tools are used to fix potential lint issues.