Skip to content

Commit 5b2578e

Browse files
authored
chore: pin vllm-rs ref and report decode stats (#461)
1 parent 328c99f commit 5b2578e

3 files changed

Lines changed: 55 additions & 7 deletions

File tree

‎install.sh‎

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
1313
EXTRAS="${PARALLAX_EXTRAS:-}"
1414
PYTHON_VERSION="${PARALLAX_PYTHON_VERSION:-3.12}"
1515
VENV_DIR="$SCRIPT_DIR/.venv"
16-
VLLM_REF="${VLLM_REF:-main}"
16+
VLLM_REF="${VLLM_REF:-v0.22.0}"
1717

1818
show_help() {
1919
cat <<'EOF'
@@ -30,7 +30,7 @@ Options:
3030
Environment:
3131
PARALLAX_EXTRAS Same as --extras.
3232
PARALLAX_PYTHON_VERSION Same as --python.
33-
VLLM_REF vLLM git branch/tag to clone. Defaults to main.
33+
VLLM_REF vLLM git branch/tag to clone. Defaults to v0.22.0.
3434
EOF
3535
}
3636

@@ -218,15 +218,28 @@ build_vllm_rust_frontend() {
218218
local rust_dir
219219
local parallax_scripts_dir
220220
local target_path
221+
local target_version_path
222+
local existing_version
221223
local toolchain
222224

223225
parallax_scripts_dir="$(resolve_venv_bin_dir)"
224226
target_path="$parallax_scripts_dir/vllm-rs"
227+
target_version_path="$target_path.version"
225228

226229
if [[ -f "$target_path" ]]; then
227-
chmod +x "$target_path"
228-
echo "vllm-rs already exists at $target_path, skipping Rust build."
229-
return
230+
existing_version=""
231+
if [[ -f "$target_version_path" ]]; then
232+
existing_version="$(<"$target_version_path")"
233+
fi
234+
if [[ "$existing_version" != "$VLLM_REF" ]]; then
235+
echo "Existing vllm-rs version (${existing_version:-unknown}) does not match $VLLM_REF, rebuilding."
236+
rm -f "$target_path" "$target_version_path"
237+
else
238+
chmod +x "$target_path"
239+
printf '%s\n' "$VLLM_REF" > "$target_version_path"
240+
echo "vllm-rs already exists at $target_path, skipping Rust build."
241+
return
242+
fi
230243
fi
231244

232245
CLONE_PARENT="$(mktemp -d "${TMPDIR:-/tmp}/parallax-vllm-rs.XXXXXX")"
@@ -264,6 +277,7 @@ build_vllm_rust_frontend() {
264277
mkdir -p "$(dirname "$target_path")"
265278
cp "$rust_dir/target/release/vllm-rs" "$target_path"
266279
chmod +x "$target_path"
280+
printf '%s\n' "$VLLM_REF" > "$target_version_path"
267281
echo "Installed vllm-rs to $target_path"
268282
cleanup_clone
269283
trap - EXIT

‎pyproject.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ mac = [
5252

5353
gpu = [
5454
"sglang[all]==0.5.12",
55+
"kernels<0.15",
5556
"accelerate",
5657
"mlx-lm==0.31.3",
5758
"mlx[cpu]==0.31.2",

‎scripts/generate.py‎

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"""
2323

2424
import argparse
25+
import statistics
2526
import time
2627

2728
import mlx.core as mx
@@ -80,6 +81,21 @@ def build_prompt(messages, tokenizer):
8081
return full_prompt, prompt_tokens
8182

8283

84+
def percentile(values, percentile_value):
85+
if not values:
86+
return 0
87+
88+
sorted_values = sorted(values)
89+
if len(sorted_values) == 1:
90+
return sorted_values[0]
91+
92+
rank = (len(sorted_values) - 1) * percentile_value / 100
93+
lower = int(rank)
94+
upper = min(lower + 1, len(sorted_values) - 1)
95+
weight = rank - lower
96+
return sorted_values[lower] * (1 - weight) + sorted_values[upper] * weight
97+
98+
8399
def main():
84100
parser = argparse.ArgumentParser(description="Simple offline inference script")
85101
parser.add_argument(
@@ -226,7 +242,7 @@ def main():
226242
print_rank(f"Token 1 (Prefill) time: {prefill_time * 1000:.2f} ms")
227243

228244
# 5. Decode Loop
229-
total_decode_time = 0
245+
decode_step_times = []
230246
for i in range(args.max_tokens - 1):
231247
if is_finished:
232248
break
@@ -260,20 +276,37 @@ def main():
260276
request.commit_new_token(token_id)
261277

262278
decode_step_time = time.perf_counter() - decode_step_start
263-
total_decode_time += decode_step_time
279+
decode_step_times.append(decode_step_time)
264280
print_rank(f"Token {i + 2} time: {decode_step_time * 1000:.2f} ms")
265281

266282
print_rank("\nGenerated Content:")
267283
print_rank(tokenizer.decode(request.output_ids))
268284

269285
# Summary Statistics
286+
total_decode_time = sum(decode_step_times)
270287
prompt_tps = request.prompt_len / prefill_time
271288
generation_tps = len(request.output_ids) / total_decode_time if total_decode_time > 0 else 0
272289
peak_mem = mx.get_peak_memory() / 1024**3
273290

274291
print_rank("-" * 20)
275292
print_rank(f"Prompt: {request.prompt_len} tokens, {prompt_tps:.3f} tokens-per-sec")
276293
print_rank(f"Generation: {len(request.output_ids)} tokens, {generation_tps:.3f} tokens-per-sec")
294+
if decode_step_times:
295+
decode_step_times_ms = [step_time * 1000 for step_time in decode_step_times]
296+
decode_step_time_mean = sum(decode_step_times_ms) / len(decode_step_times_ms)
297+
print_rank(
298+
"Decode step time (ms): "
299+
f"min={min(decode_step_times_ms):.2f}, "
300+
f"median={percentile(decode_step_times_ms, 50):.2f}, "
301+
f"max={max(decode_step_times_ms):.2f}, "
302+
f"mean={decode_step_time_mean:.2f}, "
303+
f"std={statistics.pstdev(decode_step_times_ms):.2f}, "
304+
f"p90={percentile(decode_step_times_ms, 90):.2f}, "
305+
f"p95={percentile(decode_step_times_ms, 95):.2f}, "
306+
f"p99={percentile(decode_step_times_ms, 99):.2f}"
307+
)
308+
else:
309+
print_rank("Decode step time (ms): n/a")
277310
print_rank(f"Peak memory: {peak_mem:.3f} GB")
278311
cache_manager.free_request(request.request_id)
279312

0 commit comments

Comments
 (0)