Build Rust extensions on demand in source checkouts (#34994)

This commit is contained in:
Lianmin Zheng
2026-08-16 14:58:06 -07:00
committed by GitHub
parent 0e231d365a
commit 67e12131df
39 changed files with 880 additions and 109 deletions
+5 -5
View File
@@ -11,17 +11,17 @@ license.workspace = true
# features: the wheel build needs the PyO3 bindings, which are NOT default (see
# [features] below).
[package.metadata.sglang]
python-module = "sglang.srt.multimodal._core"
python-module = "sglang.srt.rust_extensions._multimodal"
debug = false
features = ["python", "parallel"]
[lib]
# Unique per-crate artifact name (the shared workspace target/ dir cannot hold
# two `lib_core` cdylibs). The importable Python module is still `_core`: the
# name comes from the `#[pymodule]` entry point and the setuptools-rust
# `target` in python/pyproject.toml, which renames the built artifact.
# multiple `lib_core` cdylibs). The importable Python module is `_multimodal`: the
# name comes from the `#[pymodule]` entry point and the setuptools-rust target,
# which renames the built artifact.
name = "sglang_mm_core"
# cdylib: the PyO3 module (`sglang.srt.multimodal._core`).
# cdylib: the PyO3 module (`sglang.srt.rust_extensions._multimodal`).
# rlib: pure-Rust core linked by sglang-server's native MM path.
crate-type = ["cdylib", "rlib"]
+7 -6
View File
@@ -6,9 +6,9 @@ GIL-released.
Built two ways:
- **PyO3 extension** `sglang.srt.multimodal._core` (features `python,parallel`,
requested by the wheel build) via setuptools-rust when installing sglang —
used by Python processors and parity tests.
- **PyO3 extension** `sglang.srt.rust_extensions._multimodal` (features
`python,parallel`, requested by the wheel build) via setuptools-rust when
installing sglang — used by Python processors and parity tests.
- **Pure-Rust `rlib`** (default features, i.e. neither) linked by
`sglang-server`'s MM worker path — that copy needs no pyo3, no libpython, and
no rayon: it spawns no threads and runs inline on the calling thread, because
@@ -19,7 +19,7 @@ Built two ways:
```
src/
├── lib.rs # module root; PyO3 module (_core) feature-gated
├── lib.rs # module root; PyO3 module (_multimodal) feature-gated
├── pipeline.rs # the server-pipeline contract: MmFamilyProcessor
│ # trait + the carriers (Tensor, TokenLayout, ...)
├── driver.rs # model-independent request driver (fetch →
@@ -115,7 +115,7 @@ un-stripped URL to `open()`).
## Python API
```python
from sglang.srt.multimodal._core import common, inkling
from sglang.srt.rust_extensions._multimodal import common, inkling
# Common (model-agnostic)
common.resize_rgb(arr, out_w, out_h)
@@ -174,7 +174,8 @@ impl ImageProcessorSpec for MyModelProcessor {
4. Wire up in `src/lib.rs`: `mod my_model;` and `my_model::register(m)?;`.
5. Add Python processor class that calls `from sglang.srt.multimodal._core import my_model`.
5. Add Python processor class that calls
`from sglang.srt.rust_extensions._multimodal import my_model`.
## Available transform primitives (`common::transforms`)
+1 -1
View File
@@ -5,7 +5,6 @@ import numpy as np
import torch
from PIL import Image
from sglang.srt.multimodal._core import inkling as _rs_inkling
from sglang.srt.multimodal.inkling.image_processing import (
IMAGE_MEAN,
IMAGE_STD,
@@ -13,6 +12,7 @@ from sglang.srt.multimodal.inkling.image_processing import (
_encode_image_bytes,
_fill_patches_numba,
)
from sglang.srt.rust_extensions._multimodal import inkling as _rs_inkling
PS = 40
+1 -1
View File
@@ -9,4 +9,4 @@ description = "Rust-accelerated multimodal preprocessing for SGLang"
requires-python = ">=3.10"
[tool.maturin]
module-name = "_core"
module-name = "_multimodal"
+2 -2
View File
@@ -1,7 +1,7 @@
//! sglang-mm: Rust-accelerated multimodal preprocessing for SGLang.
//!
//! Built two ways:
//! * PyO3 extension `sglang.srt.multimodal._core` (feature `python`, default),
//! * PyO3 extension `sglang.srt.rust_extensions._multimodal` (feature `python`),
//! used by Python processors (e.g. Inkling) and by parity tests.
//! * Pure-Rust `rlib` (`default-features = false`), linked by `sglang-server`'s
//! MM worker path — no pyo3 in that dependency graph.
@@ -18,7 +18,7 @@ use pyo3::prelude::*;
#[cfg(feature = "python")]
#[pymodule]
fn _core(m: &Bound<'_, PyModule>) -> PyResult<()> {
fn _multimodal(m: &Bound<'_, PyModule>) -> PyResult<()> {
common::register(m)?;
inkling::register(m)?;
qwen_vl::register(m)?;
+1 -1
View File
@@ -4,7 +4,7 @@ import os
import numpy as np
import pytest
from sglang.srt.multimodal._core import inkling as _rs_inkling
from sglang.srt.rust_extensions._multimodal import inkling as _rs_inkling
GOLDEN_DIR = os.environ.get(
"INKLING_MM_GOLDEN_DIR",
+1 -1
View File
@@ -15,12 +15,12 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "bench"))
from bench_parity import make_photo_like
from sglang.srt.managers.mm_utils import data_hash, hash_feature
from sglang.srt.multimodal._core import common as _rs_common
from sglang.srt.multimodal.inkling import InklingProcessor
from sglang.srt.multimodal.inkling.image_processing_rust import (
InklingRustImageProcessor,
)
from sglang.srt.multimodal.processors import inkling as prc
from sglang.srt.rust_extensions._multimodal import common as _rs_common
def png_bytes(arr):
+2 -2
View File
@@ -6,8 +6,8 @@ import numpy as np
import pytest
from PIL import Image
from sglang.srt.multimodal._core import common as _rs_common
from sglang.srt.multimodal._core import inkling as _rs_inkling
from sglang.srt.rust_extensions._multimodal import common as _rs_common
from sglang.srt.rust_extensions._multimodal import inkling as _rs_inkling
def py_scaled_dims(