Something went wrong. Try again.
Routing embedding stack for Qwen3-Embedding-0.6B on Apple Silicon: orchestrator + MLX + llama.cpp backends
Something went wrong. Try again.
3.5 kB · 106 lines
Shell
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107#!/usr/bin/env bash# Smoke-test the running orchestrator using slices of Project Gutenberg #84# (Frankenstein). Exercises:# 1. short only -> Swift# 2. mixed short texts -> Swift# 3. long only -> spawns Rust backend# 4. mixed short + long -> Swift in parallel with Rust# 5. > 32k tokens -> HTTP 400## Assumes the orchestrator is already listening on :8080.# Run scripts/run-orchestrator.sh in another terminal first.
set -euo pipefail
ORCH="${ORCH:-http://127.0.0.1:8080}"TEXT="${TEXT:-/tmp/pg84.txt}"GUTENBERG_URL="https://www.gutenberg.org/cache/epub/84/pg84.txt"
# Fetch the book if we don't have it yet.if [ ! -f "$TEXT" ]; then echo "==> downloading $GUTENBERG_URL -> $TEXT" curl -sSL -o "$TEXT" "$GUTENBERG_URL"fi
# Sanity: orchestrator reachable?if ! curl -sf -o /dev/null "$ORCH/healthz"; then echo "orchestrator not reachable at $ORCH/healthz" echo "start it first: scripts/run-orchestrator.sh" exit 1fi
# Drive the tests through a Python helper so we can slice the text and# measure wall-clock per request cleanly.python3 - "$ORCH" "$TEXT" <<'PY'import json, sys, time, urllib.request, urllib.error
orch, text_path = sys.argv[1], sys.argv[2]book = open(text_path, encoding="utf-8").read()
# Character slices. Token counts are rough: ~1 token per 4 chars for English.slices = { "short (~125 tokens)" : book[1000:1500], "medium (~1k tokens)" : book[2000:6000], "long (~15k tokens)" : book[5000:65000], "overflow (~50k tokens)": book[:200000],}
def call(label, texts, expect_error=False): body = json.dumps({"texts": texts, "input_type": "document"}).encode() req = urllib.request.Request( f"{orch}/embed", data=body, headers={"Content-Type": "application/json"}, ) t0 = time.time() try: r = json.loads(urllib.request.urlopen(req, timeout=600).read()) dt = time.time() - t0 print(f" {label:40s} ok n={len(r['vectors'])} dim={r['dim']} " f"t={dt:.2f}s") return r except urllib.error.HTTPError as e: dt = time.time() - t0 msg = e.read().decode() tag = "PASS" if expect_error else "FAIL" print(f" {label:40s} {e.code} t={dt:.2f}s {msg} [{tag}]") if not expect_error: sys.exit(1) return None
print("== short only (Swift path) ==")a = call("short only", [slices["short (~125 tokens)"]])
print("== mixed short texts (Swift path) ==")call("short + medium", [ slices["short (~125 tokens)"], slices["medium (~1k tokens)"],])
print("== long only (spawns Rust) ==")b = call("long only", [slices["long (~15k tokens)"]])
print("== mixed short + long (Swift || Rust) ==")c = call("short + long", [ slices["short (~125 tokens)"], slices["long (~15k tokens)"],])
print("== overflow rejection ==")call("40k+ tokens", [slices["overflow (~50k tokens)"]], expect_error=True)
# Sanity: the short vector in the mixed call should match the short-only call# bit-for-bit (shorts went through Swift unchanged; merge order preserved).if a and c: v1 = a["vectors"][0][:5] v2 = c["vectors"][0][:5] match = v1 == v2 print(f"\n short-vec parity short-only vs mixed: " f"{'OK' if match else 'MISMATCH'}") if not match: print(f" short-only : {v1}") print(f" mixed : {v2}") sys.exit(1)
print("\nall smoke tests passed")PY