Repository navigation
Expand file tree
/
Copy pathpyproject.toml
More file actions
192 lines (173 loc) · 6.62 KB
/
Copy pathpyproject.toml
File metadata and controls
192 lines (173 loc) · 6.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project.urls]
"Homepage" = "https://github.com/togethercomputer/xorl"
"Source Code" = "https://github.com/togethercomputer/xorl"
[project]
name = "xorl"
dynamic = ["version"]
description = "Xorl: Simple and high-performance distributed training framework for large language models"
requires-python = "==3.12.*"
dependencies = [
# Pin the xorl-client data/evaluation chain as well as the GPU stack. Without
# these constraints, pip backtracks across years of s3fs/Inspect releases.
"aiobotocore==2.25.1",
"boto3==1.40.61",
"botocore==1.40.61",
"datasets==5.0.1",
"fsspec==2025.9.0",
"inspect-ai==0.3.255",
"packaging>=23.0,<26.0",
"tenacity>=8.0.0",
"torchdata>=0.8.0,<1.0",
"tiktoken",
# Matches the checked-in xorl-sglang tree's own transformers pin. The
# transformers 5.4+ ``validate_layer_type`` check is satisfied because the
# Qwen3.5 configs expand length-N ``layer_types`` patterns to
# ``num_hidden_layers`` entries before validation runs.
"transformers[torch]==5.12.1",
"psutil",
"s3fs==2025.9.0",
"tinker==0.25.0",
"tinker-cookbook==0.1.0",
"wandb",
"safetensors",
"einops",
"numpy<2.4",
"numba",
"pydantic",
"pyyaml",
"uvicorn",
"pyzmq",
"msgpack",
"msgspec==0.21.1",
"fastapi",
# P2P / Mooncake weight sync
"mooncake-transfer-engine==0.3.9",
"xorl-client @ git+https://github.com/togethercomputer/xorl-client.git@2a3a60a783c98e2a8ff722bad06dab18caee350c",
# PyTorch 2.11 with its CUDA 13 runtime dependencies. These versions match
# the checked-in xorl-sglang package metadata, so xorl, xorl-client, and the
# xorl-sglang submodule (including its compiled sglang-kernel extension) all
# run in this one environment.
"torch==2.11.0",
"torchvision==0.26.0",
"triton==3.6.0",
"flash-attn-4==4.0.0b19",
# Resolved to the checked-in fork by [tool.uv.sources] below.
"sglang[all]",
# TileLang kernels — used by DeepSeek-V4 sparse MLA, DSA indexer, FP8
# act-quant, the hyper-connection sinkhorn, and the vendored FlashQLA GDN
# backend. FlashQLA requires the tl_gemm builtin (>=0.1.10) AND
# prefer_instruction (tile-ai/tilelang PR #2303). PyPI 0.1.11 is the first
# release carrying #2303 and matches the pinned SGLang tree's own tilelang
# pin, so the blessed prebuilt 0.1.10+git wheel from
# togethercomputer/xorl-wheels is no longer needed — see
# src/xorl/ops/linear_attention/flashqla/VENDORED.md. Bump deliberately +
# revalidate the GPU smokes (sparse-MLA bwd NaN history and the FlashQLA
# contract-pin tests) when picking up a new build.
"tilelang==0.1.11",
# The tilelang wheel's bundled TVM dlopens the libz3.so.4.15 soname;
# z3-solver 4.16 drops it.
"z3-solver<4.16",
# Fast Hadamard transform — preferred backend for DSv4
# ops.utils.rotate_activation. Imported lazily; the helper falls back to a
# pure-torch FWHT (iterative butterfly) when the wheel is unavailable, so
# the package is intentionally NOT a hard dep — its sdist needs torch at
# build-isolation time, which trips uv's CPU-tests installer.
# Install on demand for the perf-sensitive path:
# uv pip install fast-hadamard-transform
]
[project.scripts]
xorl-sim-calibrate = "xorl.sim.calibration_evaluator:main"
xorl-sim-collect = "xorl.sim.collect_calibration:main"
xorl-sim-feasibility = "xorl.sim.feasibility_evaluator:main"
xorl-sim-kernels = "xorl.sim.kernel_variants:main"
xorl-sim-packs = "xorl.sim.calibration_packs:main"
xorl-sim-plan = "xorl.sim.scenario_planner:main"
xorl-sim-predict = "xorl.sim.predict:main"
xorl-sim-rank = "xorl.sim.tradeoff_ranker:main"
xorl-sim-validate = "xorl.sim.validate:main"
[dependency-groups]
# Follow the best practice in https://docs.astral.sh/uv/concepts/projects/dependencies/#development-dependencies
# to manage dev dependencies (i.e., dependencies that are only used in development) like
# test, lint and doc tools.
dev = [
{include-group = "lint"},
{include-group = "test"},
]
lint = [
"pre-commit>=4.5,<5",
"ruff",
]
test = [
"pytest",
"pytest-asyncio",
"expecttest"
]
[tool.uv]
# This locks the uv version so that we have a consistent uv behavior across the board.
# Inconsistent uv versions might generate different uv lock files which creates chaos.
#
# NOTE 1: Update this at least once per month as uv releases new version every week.
# NOTE 2: When updating this line, make sure to update Dockerfile under docker/ to the same
# version and release new docker images.
required-version = ">=0.8.14"
override-dependencies = [
# XoRL's Quack imports use the pre-4.6 CUTLASS API (nvidia-cutlass-dsl 4.6.0
# removed cutlass.cute.core.ThrCopy, which the Quack compatibility layer
# still needs at import time). The pinned SGLang hash_topk, LoRA, and
# sgl-kernel paths are qualified with this ABI pair.
"nvidia-cutlass-dsl==4.5.2",
"quack-kernels==0.5.0",
]
[tool.uv.sources]
sglang = { path = "submodules/xorl-sglang/python", editable = true }
[tool.setuptools.dynamic]
version = {attr = "xorl.__version__"}
[tool.setuptools.packages.find]
where = ["src"]
[tool.setuptools.package-data]
"xorl.sim" = ["README.md", "calibration_packs/**/*"]
[tool.ruff]
target-version = "py312"
line-length = 120
[tool.ruff.lint]
ignore = ["C901", "E501", "E741", "W605", "C408"]
select = ["C", "E", "F", "I", "W", "PLC0415", "TID253"]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["E402", "F401", "F403", "F811"]
"tests/**/*.py" = ["PLC0415"]
[tool.ruff.lint.isort]
lines-after-imports = 2
known-first-party = ["xorl"]
known-third-party = ["torch", "transformers", "wandb"]
[tool.ruff.lint.flake8-tidy-imports]
banned-module-level-imports = [
"wandb",
"flash_attn",
"liger_kernel.transformers.fused_linear_cross_entropy",
]
[tool.pytest.ini_options]
addopts = "-v"
markers = [
"cpu: CPU-only tests (no GPU required)",
"gpu: Tests that require GPU",
"e2e: End-to-end tests (full system, require GPU and torchrun)",
"server: Tests for the training server (API, orchestrator, runner)",
"distributed: Tests that require distributed setup (torchrun)",
"slow: Tests that take a long time to run",
"benchmark: Performance benchmark tests",
"collator: Tests for data collators",
"dataloader: Tests for data loaders",
]
testpaths = ["tests"]
# distributed_utils.py and other shared test helpers live alongside the
# distributed tests; put that directory on sys.path so test files can
# import them by bare module.
pythonpath = ["tests/distributed"]
norecursedirs = ["submodules"]
filterwarnings = [
"ignore::DeprecationWarning:multiprocessing.popen_fork",
"ignore:The argument 'device' of Tensor:DeprecationWarning",
]