Skip to content

Commit 55929b0

Browse files
authored
Merge pull request #6456 from hpcaitech/chore/requirements-cleanup
chore: clean up project requirements
2 parents be1a04a + a1950b0 commit 55929b0

31 files changed

Lines changed: 254 additions & 325 deletions

File tree

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: Requirements Compatibility
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
paths:
7+
- ".github/workflows/requirements_compatibility.yml"
8+
- ".pre-commit-config.yaml"
9+
- "applications/*/setup.py"
10+
- "applications/ColossalChat/coati/distributed/reward/code_reward/testing_util.py"
11+
- "applications/ColossalChat/requirements.txt"
12+
- "applications/ColossalChat/tests/test_code_reward_testing_util.py"
13+
- "examples/community/roberta/pretraining/model/deberta_v2.py"
14+
- "examples/images/diffusion/ldm/modules/image_degradation/utils_image.py"
15+
- "requirements/**"
16+
- "setup.py"
17+
- "tests/test_cluster/test_process_group_mesh.py"
18+
19+
jobs:
20+
compatibility:
21+
name: Python ${{ matrix.python-version }} / ${{ matrix.numpy-requirement }}
22+
runs-on: ubuntu-latest
23+
strategy:
24+
fail-fast: false
25+
matrix:
26+
include:
27+
- python-version: "3.10"
28+
numpy-requirement: "numpy==1.26.*"
29+
- python-version: "3.10"
30+
numpy-requirement: "numpy>=2,<3"
31+
- python-version: "3.11"
32+
numpy-requirement: "numpy>=2,<3"
33+
- python-version: "3.12"
34+
numpy-requirement: "numpy>=2,<3"
35+
36+
steps:
37+
- uses: actions/checkout@v4
38+
39+
- uses: actions/setup-python@v5
40+
with:
41+
python-version: ${{ matrix.python-version }}
42+
cache: pip
43+
cache-dependency-path: requirements/requirements.txt
44+
45+
- name: Install compatibility test dependencies
46+
run: |
47+
python -m pip install --upgrade pip setuptools wheel
48+
python -m pip install torch==2.5.1 --index-url https://download.pytorch.org/whl/cpu
49+
python -m pip install "${{ matrix.numpy-requirement }}" packaging psutil pytest ruff==0.16.9
50+
python -m pip install --no-deps -e .
51+
52+
- name: Verify package metadata
53+
run: |
54+
python - <<'PY'
55+
from importlib.metadata import metadata, requires
56+
from packaging.requirements import Requirement
57+
from packaging.specifiers import SpecifierSet
58+
from packaging.version import Version
59+
60+
package_metadata = metadata("colossalai")
61+
python_versions = SpecifierSet(package_metadata["Requires-Python"])
62+
assert Version("3.9") not in python_versions
63+
assert all(Version(version) in python_versions for version in ("3.10", "3.11", "3.12"))
64+
assert Version("3.13") not in python_versions
65+
66+
requirements = {Requirement(item).name.lower() for item in requires("colossalai") or []}
67+
assert "pre-commit" not in requirements
68+
PY
69+
70+
- name: Check removed NumPy APIs
71+
run: ruff check --select NPY201 colossalai tests applications examples
72+
73+
- name: Run compatibility smoke tests
74+
run: |
75+
pytest -m cpu tests/test_cluster/test_process_group_mesh.py
76+
pytest applications/ColossalChat/tests/test_code_reward_testing_util.py

‎.pre-commit-config.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ repos:
1919
hooks:
2020
- id: black
2121
name: black formatter
22-
args: ['--line-length=120', '--target-version=py37', '--target-version=py38', '--target-version=py39','--target-version=py310']
22+
args: ['--line-length=120', '--target-version=py310', '--target-version=py311', '--target-version=py312']
2323

2424
- repo: https://github.com/pre-commit/mirrors-clang-format
2525
rev: v19.1.5

‎CONTRIBUTING.md‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ To set up the environment for unit testing, first change your current directory
3434
```bash
3535
pip install -r requirements/requirements-test.txt
3636
```
37-
If you encounter an error telling "Could not find a version that satisfies the requirement fbgemm-gpu==0.2.0", please downgrade your python version to 3.8 or 3.9 and try again.
3837

3938
If you only want to run CPU tests, you can run
4039

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ Please visit our [documentation](https://www.colossalai.org/) and [examples](htt
469469

470470
Requirements:
471471
- PyTorch >= 2.2
472-
- Python >= 3.7
472+
- Python >= 3.10 and < 3.13
473473
- CUDA >= 11.0
474474
- [NVIDIA GPU Compute Capability](https://developer.nvidia.com/cuda-gpus) >= 7.0 (V100/RTX20 and higher)
475475
- Linux OS

‎applications/Colossal-LLaMA/setup.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@ def fetch_version():
2626
license="Apache Software License 2.0",
2727
url="https://github.com/hpcaitech/ColossalAI/tree/main/applications/Colossal-LLaMA",
2828
install_requires=fetch_requirements("requirements.txt"),
29-
python_requires=">=3.7",
29+
python_requires=">=3.10,<3.13",
3030
classifiers=[
3131
"Programming Language :: Python :: 3",
32+
"Programming Language :: Python :: 3.10",
33+
"Programming Language :: Python :: 3.11",
34+
"Programming Language :: Python :: 3.12",
3235
"License :: OSI Approved :: Apache Software License",
3336
"Environment :: GPU :: NVIDIA CUDA",
3437
"Topic :: Scientific/Engineering :: Artificial Intelligence",

‎applications/ColossalChat/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ More details can be found in the latest news.
8989

9090
```bash
9191
# Create new environment
92-
conda create -n colossal-chat python=3.10.9 (>=3.8.7)
92+
conda create -n colossal-chat python=3.10.9 # supported versions: >=3.10,<3.13
9393
conda activate colossal-chat
9494

9595
# Clone ColossalAI

‎applications/ColossalChat/coati/distributed/reward/code_reward/testing_util.py‎

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,30 @@
3232

3333
# for capturing the stdout
3434
from io import StringIO
35+
from types import ModuleType
3536

3637
# used for testing the code that reads from input
3738
from unittest.mock import mock_open, patch
3839

3940
import numpy as np
40-
from pyext import RuntimeModule
41+
42+
43+
def _load_runtime_module(name: str, source: str) -> ModuleType:
44+
"""Compile source code into an isolated in-memory module."""
45+
module = ModuleType(name)
46+
module.__file__ = "<string>"
47+
code = compile(source, module.__file__, "exec")
48+
previous_module = sys.modules.get(name)
49+
sys.modules[name] = module
50+
try:
51+
exec(code, module.__dict__)
52+
except Exception:
53+
if previous_module is None:
54+
sys.modules.pop(name, None)
55+
else:
56+
sys.modules[name] = previous_module
57+
raise
58+
return module
4159

4260

4361
def truncatefn(s, length=300):
@@ -125,7 +143,7 @@ def run_test(in_outs, test=None, debug=False, timeout=15, run_all_tests=False):
125143
print(f"sol = {sol}")
126144
signal.alarm(timeout)
127145
try:
128-
tmp_sol = RuntimeModule.from_string("tmp_sol", "", sol)
146+
tmp_sol = _load_runtime_module("tmp_sol", sol)
129147
tmp = tmp_sol if "class Solution" not in test else tmp_sol.Solution()
130148
signal.alarm(0)
131149
except Exception as e:
@@ -183,7 +201,7 @@ def run_test(in_outs, test=None, debug=False, timeout=15, run_all_tests=False):
183201
method_name = "code"
184202
signal.alarm(timeout)
185203
try:
186-
tmp_sol = RuntimeModule.from_string("tmp_sol", "", sol)
204+
tmp_sol = _load_runtime_module("tmp_sol", sol)
187205
tmp = tmp_sol
188206
signal.alarm(0)
189207
except Exception as e:

‎applications/ColossalChat/requirements.txt‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,3 @@ tiktoken
2424
jsonlines
2525
math_verify
2626
latex2sympy2_extended
27-
pyext

‎applications/ColossalChat/setup.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@ def fetch_version():
3232
license="Apache Software License 2.0",
3333
url="https://github.com/hpcaitech/Coati",
3434
install_requires=fetch_requirements("requirements.txt"),
35-
python_requires=">=3.7",
35+
python_requires=">=3.10,<3.13",
3636
classifiers=[
3737
"Programming Language :: Python :: 3",
38+
"Programming Language :: Python :: 3.10",
39+
"Programming Language :: Python :: 3.11",
40+
"Programming Language :: Python :: 3.12",
3841
"License :: OSI Approved :: Apache Software License",
3942
"Environment :: GPU :: NVIDIA CUDA",
4043
"Topic :: Scientific/Engineering :: Artificial Intelligence",
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import subprocess
2+
import sys
3+
import traceback
4+
from pathlib import Path
5+
6+
import pytest
7+
8+
from applications.ColossalChat.coati.distributed.reward.code_reward.testing_util import _load_runtime_module
9+
10+
REPO_ROOT = Path(__file__).resolve().parents[3]
11+
MODULE_NAME = "_colossalai_test_candidate"
12+
13+
14+
@pytest.fixture(autouse=True)
15+
def cleanup_runtime_module():
16+
yield
17+
sys.modules.pop(MODULE_NAME, None)
18+
19+
20+
def _run_isolated(script: str):
21+
completed = subprocess.run(
22+
[sys.executable, "-c", script],
23+
cwd=REPO_ROOT,
24+
capture_output=True,
25+
text=True,
26+
timeout=30,
27+
)
28+
assert completed.returncode == 0, completed.stdout + completed.stderr
29+
30+
31+
def test_load_runtime_module_supports_functions_and_solution_classes():
32+
module = _load_runtime_module(
33+
MODULE_NAME,
34+
"def add(a, b):\n return a + b\n\nclass Solution:\n def double(self, value):\n return value * 2\n",
35+
)
36+
37+
assert module.__name__ == MODULE_NAME
38+
assert module.add(2, 3) == 5
39+
assert module.Solution().double(4) == 8
40+
41+
42+
def test_load_runtime_module_does_not_share_namespaces():
43+
first = _load_runtime_module(MODULE_NAME, "value = 1")
44+
second = _load_runtime_module(MODULE_NAME, "value = 2")
45+
46+
assert first is not second
47+
assert first.value == 1
48+
assert second.value == 2
49+
assert sys.modules[MODULE_NAME] is second
50+
51+
52+
def test_load_runtime_module_supports_dataclasses():
53+
module = _load_runtime_module(
54+
MODULE_NAME,
55+
"from dataclasses import dataclass\n\n@dataclass\nclass Point:\n x: int\n y: int\n",
56+
)
57+
58+
assert module.Point(2, 3) == module.Point(x=2, y=3)
59+
60+
61+
def test_load_runtime_module_uses_string_filename_in_tracebacks():
62+
previous = _load_runtime_module(MODULE_NAME, "value = 1")
63+
64+
with pytest.raises(RuntimeError) as exc_info:
65+
_load_runtime_module(MODULE_NAME, "raise RuntimeError('boom')")
66+
67+
frames = traceback.extract_tb(exc_info.value.__traceback__)
68+
assert frames[-1].filename == "<string>"
69+
assert sys.modules[MODULE_NAME] is previous
70+
71+
72+
def test_load_runtime_module_reports_syntax_errors():
73+
with pytest.raises(SyntaxError) as exc_info:
74+
_load_runtime_module(MODULE_NAME, "def broken(:\n pass")
75+
76+
assert exc_info.value.filename == "<string>"
77+
78+
79+
@pytest.mark.skipif(sys.platform == "win32", reason="The code verifier uses Unix process controls")
80+
def test_run_test_executes_call_based_code_without_pyext():
81+
_run_isolated(
82+
"""
83+
from applications.ColossalChat.coati.distributed.reward.code_reward.testing_util import run_test
84+
85+
result, metadata = run_test(
86+
{"fn_name": "add", "inputs": ["2\\n3"], "outputs": ["5"]},
87+
test="def add(a, b):\\n return a + b",
88+
)
89+
assert result == [True], (result, metadata)
90+
"""
91+
)
92+
93+
94+
@pytest.mark.skipif(sys.platform == "win32", reason="The code verifier uses Unix process controls")
95+
def test_run_test_executes_standard_input_code_without_pyext():
96+
_run_isolated(
97+
"""
98+
from applications.ColossalChat.coati.distributed.reward.code_reward.testing_util import run_test
99+
100+
result, metadata = run_test(
101+
{"inputs": ["4"], "outputs": ["8"]},
102+
test="value = int(input())\\nprint(value * 2)",
103+
)
104+
assert result == [True], (result, metadata)
105+
"""
106+
)

0 commit comments

Comments
 (0)