Skip to content

Commit f1774c5

Browse files
authored
fix ci/pypi (#30)
1 parent d8db548 commit f1774c5

File tree

3 files changed

+146
-8
lines changed

3 files changed

+146
-8
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ If you want to modify the code or try the metal implementation set the project u
152152

153153
```shell
154154
git clone https://github.com/openai/gpt-oss.git
155-
pip install -e ".[metal]"
155+
GPTOSS_BUILD_METAL=1 pip install -e ".[metal]"
156156
```
157157

158158
## Download the model
@@ -228,6 +228,7 @@ python gpt_oss/metal/scripts/create-local-model.py -s <model_dir> -d <output_fil
228228
```
229229

230230
Or downloaded the pre-converted weight:
231+
231232
```shell
232233
huggingface-cli download openai/gpt-oss-120b --include "metal/*" --local-dir gpt-oss-120b/metal/
233234
huggingface-cli download openai/gpt-oss-20b --include "metal/*" --local-dir gpt-oss-20b/metal/
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
"""
2+
Build backend for gpt-oss that supports two modes:
3+
4+
1) Default (pure wheel for PyPI)
5+
- Delegates to setuptools.build_meta.
6+
- Produces a py3-none-any wheel so PyPI accepts it (no linux_x86_64 tag).
7+
8+
2) Optional Metal/C extension build (local only)
9+
- If the environment variable GPTOSS_BUILD_METAL is set to a truthy value
10+
(1/true/on/yes), delegates to scikit_build_core.build.
11+
- Dynamically injects build requirements (scikit-build-core, cmake, ninja,
12+
pybind11) only for this mode.
13+
14+
Why this is needed
15+
- PyPI rejects Linux wheels tagged linux_x86_64; manylinux/musllinux is required
16+
for binary wheels. We ship a pure wheel by default, but still allow developers
17+
to build/install the native Metal backend locally when needed.
18+
19+
Typical usage
20+
- Publish pure wheel: `python -m build` (do not set GPTOSS_BUILD_METAL).
21+
- Local Metal dev: `GPTOSS_BUILD_METAL=1 pip install -e ".[metal]"`.
22+
- CI: keep GPTOSS_BUILD_METAL unset for releases; set it in internal jobs that
23+
exercise the extension.
24+
25+
Notes
26+
- The base package remains importable without the extension. The Metal backend
27+
is only used when `gpt_oss.metal` is explicitly imported.
28+
- This file is discovered via `backend-path = ["_build"]` and
29+
`build-backend = "gpt_oss_build_backend.backend"` in pyproject.toml.
30+
"""
31+
import os
32+
from importlib import import_module
33+
from typing import Any, Mapping, Sequence
34+
35+
36+
TRUE_VALUES = {"1", "true", "TRUE", "on", "ON", "yes", "YES"}
37+
38+
39+
def _use_metal_backend() -> bool:
40+
return str(os.environ.get("GPTOSS_BUILD_METAL", "")).strip() in TRUE_VALUES
41+
42+
43+
def _setuptools_backend():
44+
from setuptools import build_meta as _bm # type: ignore
45+
46+
return _bm
47+
48+
49+
def _scikit_build_backend():
50+
return import_module("scikit_build_core.build")
51+
52+
53+
def _backend():
54+
return _scikit_build_backend() if _use_metal_backend() else _setuptools_backend()
55+
56+
57+
# Required PEP 517 hooks
58+
59+
def build_wheel(
60+
wheel_directory: str,
61+
config_settings: Mapping[str, Any] | None = None,
62+
metadata_directory: str | None = None,
63+
) -> str:
64+
return _backend().build_wheel(wheel_directory, config_settings, metadata_directory)
65+
66+
67+
def build_sdist(
68+
sdist_directory: str, config_settings: Mapping[str, Any] | None = None
69+
) -> str:
70+
return _backend().build_sdist(sdist_directory, config_settings)
71+
72+
73+
def prepare_metadata_for_build_wheel(
74+
metadata_directory: str, config_settings: Mapping[str, Any] | None = None
75+
) -> str:
76+
# Fallback if backend doesn't implement it
77+
be = _backend()
78+
fn = getattr(be, "prepare_metadata_for_build_wheel", None)
79+
if fn is None:
80+
# setuptools exposes it; scikit-build-core may not. Defer to building a wheel for metadata.
81+
return _setuptools_backend().prepare_metadata_for_build_wheel(
82+
metadata_directory, config_settings
83+
)
84+
return fn(metadata_directory, config_settings)
85+
86+
87+
# Optional hooks
88+
89+
def build_editable(
90+
editable_directory: str, config_settings: Mapping[str, Any] | None = None
91+
) -> str:
92+
be = _backend()
93+
fn = getattr(be, "build_editable", None)
94+
if fn is None:
95+
# setuptools implements build_editable; if not available, raise the standard error
96+
raise RuntimeError("Editable installs not supported by the selected backend")
97+
return fn(editable_directory, config_settings)
98+
99+
100+
def get_requires_for_build_wheel(
101+
config_settings: Mapping[str, Any] | None = None,
102+
) -> Sequence[str]:
103+
if _use_metal_backend():
104+
# Add dynamic build requirements only when building the Metal backend
105+
return [
106+
"scikit-build-core>=0.10",
107+
"pybind11>=2.12",
108+
"cmake>=3.26",
109+
"ninja",
110+
]
111+
# setuptools usually returns []
112+
return list(_setuptools_backend().get_requires_for_build_wheel(config_settings))
113+
114+
115+
def get_requires_for_build_sdist(
116+
config_settings: Mapping[str, Any] | None = None,
117+
) -> Sequence[str]:
118+
# No special requirements for SDist
119+
be = _backend()
120+
fn = getattr(be, "get_requires_for_build_sdist", None)
121+
if fn is None:
122+
return []
123+
return list(fn(config_settings))
124+
125+
126+
def get_requires_for_build_editable(
127+
config_settings: Mapping[str, Any] | None = None,
128+
) -> Sequence[str]:
129+
if _use_metal_backend():
130+
return [
131+
"scikit-build-core>=0.10",
132+
"pybind11>=2.12",
133+
"cmake>=3.26",
134+
"ninja",
135+
]
136+
be = _setuptools_backend()
137+
fn = getattr(be, "get_requires_for_build_editable", None)
138+
if fn is None:
139+
return []
140+
return list(fn(config_settings))

pyproject.toml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,16 @@ requires-python = ">=3.12,<3.13"
2323
version = "0.0.1"
2424

2525
[project.optional-dependencies]
26-
triton = [
27-
"triton",
28-
"safetensors>=0.5.3",
29-
"torch>=2.7.0",
30-
]
26+
triton = ["triton", "safetensors>=0.5.3", "torch>=2.7.0"]
3127
torch = ["safetensors>=0.5.3", "torch>=2.7.0"]
3228
metal = ["numpy", "tqdm", "safetensors", "torch"]
3329
test = ["pytest>=8.4.1", "httpx>=0.28.1"]
3430
eval = ["pandas", "numpy", "openai", "jinja2", "tqdm", "blobfile"]
3531

3632
[build-system]
37-
requires = ["scikit-build-core>=0.9", "pybind11>=2.12", "cmake>=3.26", "ninja"]
38-
build-backend = "scikit_build_core.build"
33+
requires = ["setuptools>=68"]
34+
build-backend = "gpt_oss_build_backend.backend"
35+
backend-path = ["_build"]
3936

4037
[tool.setuptools]
4138
packages = ["gpt_oss"]

0 commit comments

Comments
 (0)