Skip to content

[Feature] Free-Threaded Python (3.14t / nogil) Support for SGLang #22889

Description

@liusy58

Motivation

CPython 3.13 introduced an experimental free-threaded build (PEP 703) that removes the Global Interpreter Lock (GIL). CPython 3.14t is the first release where this build is stable enough for production use, and the ecosystem of packages with free-threading wheels is growing rapidly.

vLLM has demonstrated (vllm-project/vllm#28762) that a large-scale CUDA-accelerated serving framework can run under a free-threaded interpreter. SGLang shares a similar dependency footprint and architecture. Enabling free-threaded support would unlock true CPU-level parallelism in the Python layer — benefiting the tokenizer manager, scheduler, HTTP server, disaggregation controller, and other asyncio + thread-pool components that today serialize behind the GIL.

This RFC tracks the dependency readiness, identifies the internal code changes needed, and proposes a phased plan to make uv pip install sglang work out of the box in a clean Python 3.14t environment on Linux x86-64 (CPU and CUDA).

Background

Term Meaning
3.14t The free-threaded (no-GIL) CPython 3.14 build, identified by the t suffix in the ABI tag (cp314t).
cp314 The regular (with-GIL) CPython 3.14 build.
Stable ABI A subset of the CPython C API that is ABI-compatible across Python versions (PEP 384). Extensions built against the stable ABI only need one wheel per platform, not one per Python minor version.
Py_GIL_DISABLED The compile-time macro set in free-threaded builds. C extensions must check this to use thread-safe reference counting and data structures.

Why 3.14t and not 3.13t?

  • CPython 3.14t itself is significantly more stable than 3.13t.
  • Key packages (cffi, aiohttp, etc.) support 3.14t but will not back-port to 3.13t.
  • PyTorch 2.10.0 (January 2026) will ship full cp314t wheels; PyTorch 2.9.0 already has "preview" wheels.

Prerequisites

Free-threaded Python support depends on SGLang first supporting regular Python 3.14 (with-GIL). This RFC assumes that prerequisite is met or being tracked separately.

Dependency Audit

The following tables categorize every SGLang dependency with compiled (C/C++/Rust/CUDA) code by its current free-threading readiness. Pure-Python packages are omitted — they work automatically.

Core Dependencies (from pyproject.toml dependencies)

Package Current Version cp314t Wheels on PyPI Builds from Source Tracking Issue Notes
torch 2.9.1 Preview (2.9.0); full in 2.10.0 Yes Core dependency. 2.10.0 (Jan 2026) is the target.
torchaudio 2.9.1 Follows torch Yes
torchvision latest Follows torch Yes
torchao 0.9.0 Follows torch TBD
sglang-kernel 0.4.1 ❌ No ❌ Needs work SGLang-owned. Uses stable ABI (cp310). Needs Py_GIL_DISABLED audit. See below.
flash-attn-4 ≥4.0.0b4 ❌ No TBD CUDA extension.
flashinfer_python 0.6.7.post2 ❌ No Resolved flashinfer-ai/flashinfer#1687 Uses stable ABI; fix was to not use limited API with free-threaded Python.
flashinfer_cubin 0.6.7.post2 ❌ No TBD Binary CUDA kernels, may need rebuild only.
cuda-python 12.9 TBD TBD NVIDIA-maintained.
xgrammar 0.1.32 ✅ Yes (≥0.1.31) ✅ Yes xgrammar#500 Full support.
llguidance ≥0.7.11 ✅ Yes (≥1.6.0) ✅ Yes llguidance#256 Full support.
msgspec latest ✅ Yes (≥0.20.0) ✅ Yes Full support.
outlines 0.1.11 TBD (outlines-core) ✅ Yes outlines-core#248 Depends on outlines-core.
sentencepiece latest TBD TBD C++ extension.
tiktoken latest TBD TBD Rust extension.
orjson latest ✅ Yes ✅ Yes Rust extension, typically early adopter.
pyzmq ≥25.1.2 ✅ Yes ✅ Yes
numpy latest ✅ Yes ✅ Yes
scipy latest ✅ Yes ✅ Yes
aiohttp latest ✅ Yes ✅ Yes Supports 3.14t.
pybase64 latest TBD TBD C extension.
setproctitle latest TBD TBD C extension.
nvidia-ml-py latest Pure Python N/A
pillow latest ✅ Yes ✅ Yes
pydantic latest ✅ Yes ✅ Yes Rust-compiled core.
uvloop latest TBD TBD C extension (libuv). Critical for asyncio perf.
soundfile 0.13.1 TBD TBD CFFI-based.
compressed-tensors latest TBD TBD
quack-kernels ≥0.3.0 ❌ No TBD CUDA extension.
kernels latest TBD TBD
smg-grpc-servicer ≥0.5.0 TBD TBD gRPC bindings.

Optional Dependencies (diffusion, ray, tracing)

Package cp314t Status Notes
ray ❌ No 3.14 support at all Made optional in vLLM. SGLang already has it as optional ([ray]). Not blocking.
opencv-python-headless ❌ No Diffusion extra only. Tracking: opencv/opencv#27933, build fix PR: opencv-python#1051.
xformers ✅ Yes (≥0.0.35) Resolved by removing CPython C API dependency.

SGLang-Owned Compiled Components

Component Language Build System Free-Threading Status
sgl-kernel C++17 / CUDA scikit-build-core + CMake ❌ Uses stable ABI (cp310). Needs Py_GIL_DISABLED audit and potentially per-version builds.
cpp_radix_tree (radix cache) C++ pybind11 (torch extension) ❌ Needs thread-safety audit.
ngram_corpus_ffi C++ pybind11 (torch extension) ❌ Needs thread-safety audit.
hf3fs_utils C++ pybind11 (torch extension) ⚠️ Uses py::gil_scoped_release. Needs Py_GIL_DISABLED review.
sgl-model-gateway (router) Rust (PyO3) maturin ✅ PyO3 has free-threading support.
multimodal_gen CUDA kernels C++ / CUDA setuptools ❌ Needs audit.

Internal Code Audit

GIL-Dependent Patterns

The following patterns in SGLang's Python code rely on the GIL for correctness and must be reviewed:

  1. Explicit GIL assumptions. staging_handler.py documents: "CPython GIL guarantees ordering" for flag visibility between threads. Under free-threading, this needs an explicit memory barrier or threading.Event.

  2. py::gil_scoped_release in C++ extensions. hf3fs_utils.cpp uses py::gil_scoped_release to release the GIL during memcpy. Under free-threading, pybind11's gil_scoped_release is a no-op, but the surrounding data structures must be thread-safe without the GIL.

  3. Shared mutable state across threads. The following areas use thread pools or daemon threads that share mutable Python objects:

    • TokenizerManager: ThreadPoolExecutor for tokenization with shared request queues
    • CacheController: background threads for cache management
    • KVEvents: daemon threads for ZMQ event distribution
    • weight_utils.py: multi-threaded safetensors loading with shared iterators
  4. Module-level mutable globals. Several modules use module-level dicts/lists as registries (model registry, format registry, etc.). Under free-threading, concurrent imports or first-access initialization can race.

  5. asyncio + ThreadPoolExecutor interaction. run_coroutine_threadsafe and call_soon_threadsafe are used throughout the disaggregation layer. These are asyncio-safe but the callbacks they schedule may access shared state without locks.

Thread-Safety Classification

Risk Level Pattern Example Locations Mitigation
High GIL-ordering assumptions staging_handler.py:192 Replace with threading.Event or atomics
High Shared mutable containers across threads weight_utils.py (iterator sharing) Add threading.Lock or use queue.Queue
Medium Module-level mutable registries Model/format registries Use threading.Lock for lazy init
Medium concurrent.futures with shared closures async_dynamic_batch_tokenizer.py Audit closure captures
Low py::gil_scoped_release in C++ hf3fs_utils.cpp Verify data is not shared with Python threads
Low Pure asyncio code (single-threaded event loop) HTTP server, tokenizer manager main loop Safe by design (single-threaded)

Proposed Plan

Phase 0: Python 3.14 (with-GIL) Support

Goal: pip install sglang works on regular Python 3.14.

Phase 1: Dependency Readiness Tracking

Goal: All dependencies are installable in a 3.14t environment.

Phase 2: sgl-kernel Free-Threading Support

Goal: sglang-kernel builds and passes tests under 3.14t.

Phase 3: Internal C++ Extension Audit

Goal: All SGLang-owned C++ extensions are thread-safe without the GIL.

Phase 4: Python-Level Thread-Safety Fixes

Goal: SGLang's Python code does not rely on GIL for correctness.

Phase 5: CI and Release

Goal: Free-threaded builds are tested and released.

Phase 6: Performance Validation and Optimization

Goal: Quantify the benefit of free-threading for SGLang workloads.

References

Related resources

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions