3.5 KiB
Build-Time Patches
Patches in scripts/patches/ are applied during the build process (build.sh and build_external_python.sh) to modify source files before packaging. They are automatically cleaned up on exit via the cleanup_patches() trap.
These patches exist separately from the main source to keep the development codebase clean while applying build-specific fixes and enhancements to the packaged binary.
Status
| Patch | Upstream Fix? | Why Still Needed |
|---|---|---|
| cli.patch | No | main still hardcodes supervise=True. Build scripts still use the two-tier parent/child architecture requiring MLXK2_SUPERVISE=0 to prevent double supervision. |
| server_models.patch | No | main still filters out unhealthy models with health != "healthy" check. |
| server_streaming_usage.patch | No | main still uses rough len(text.split()) * 1.3 estimation in count_tokens() with no tokenizer parameter. Streaming responses have no usage block. |
| runner_decode.patch | No | main still uses _decode_tokens() which resets and re-processes all tokens on every call (O(n^2)). The issue is in this project's usage pattern, not an upstream mlx-lm bug. |
cli.patch
File: mlxk2/cli.py
Adds the MLXK2_SUPERVISE environment variable to allow disabling subprocess uvicorn supervision.
The packaged binary uses a two-tier server architecture: a parent process (PyInstaller wrapper) spawns and supervises a child process that runs the actual uvicorn server. The parent handles graceful shutdown (SIGTERM then SIGKILL). Without this patch, the child would also try to spawn its own supervised subprocess, creating redundant nesting. Setting MLXK2_SUPERVISE=0 lets the child run the server in-process.
server_models.patch
File: mlxk2/core/server_base.py
Removes the health != "healthy" filter from the /v1/models endpoint, keeping only the runtime_compatible filter.
The health field indicates file integrity issues (corrupted files, missing snapshots), while runtime_compatible indicates feature compatibility (e.g., vision model without mlx-vlm installed). By filtering out unhealthy models entirely, users had no way to see why a model disappeared from the list. With this patch, unhealthy models remain visible with their status, so users can diagnose and repair them.
server_streaming_usage.patch
File: mlxk2/core/server_base.py
Adds token usage statistics to streaming responses and switches count_tokens() from rough word-count estimation to actual tokenizer-based counting.
The OpenAI streaming API spec includes a usage block (prompt_tokens, completion_tokens, total_tokens) in the final SSE chunk. Without this patch, streaming responses omit usage entirely, and non-streaming responses use an inaccurate len(text.split()) * 1.3 approximation. The patch accumulates generated text during streaming, counts tokens via tokenizer.encode(), and includes the usage block in the final chunk.
runner_decode.patch
File: mlxk2/core/runner/__init__.py
Replaces self._decode_tokens() with self.tokenizer.decode() to fix an O(n^2) performance regression during streaming inference.
The custom _decode_tokens() method calls detokenizer.reset() and re-processes all tokens on every invocation. When called in the streaming loop for each new token, this causes quadratic complexity, dropping inference speed from ~200 tokens/sec to ~5 tokens/sec. Using tokenizer.decode() directly is a single-pass O(n) operation and handles BPE space markers correctly.