Merge remote-tracking branch 'origin/main' into fix/torchcodec-torch211
This commit is contained in:
commit
8ca1764e46
265 changed files with 33897 additions and 1883 deletions
|
|
@ -40,7 +40,7 @@ def _registrations(source):
|
|||
|
||||
|
||||
def test_cpo_registration_matches_orpo():
|
||||
regs = _registrations(open(RL_PATH).read())
|
||||
regs = _registrations(open(RL_PATH, encoding = "utf-8").read())
|
||||
shared = {"orpo_trainer_text_tokenizer", "orpo_trainer_processor_pad_token"}
|
||||
assert shared <= set(regs.get("orpo_trainer", []))
|
||||
assert shared <= set(regs.get("cpo_trainer", []))
|
||||
|
|
@ -48,7 +48,7 @@ def test_cpo_registration_matches_orpo():
|
|||
|
||||
def _load_pad_rewriter():
|
||||
"""Exec orpo_trainer_processor_pad_token (+ _PAD_FALLBACK) without importing unsloth."""
|
||||
tree = ast.parse(open(RL_PATH).read())
|
||||
tree = ast.parse(open(RL_PATH, encoding = "utf-8").read())
|
||||
nodes = []
|
||||
for n in tree.body:
|
||||
if isinstance(n, ast.Assign) and any(
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ RL_PATH = os.path.join(REPO_ROOT, "unsloth", "models", "rl_replacements.py")
|
|||
|
||||
|
||||
def _load_helpers():
|
||||
src = open(RL_PATH).read()
|
||||
src = open(RL_PATH, encoding = "utf-8").read()
|
||||
tree = ast.parse(src)
|
||||
import torch as _torch
|
||||
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ class TestBeforeAfterImportChain:
|
|||
mm = types.ModuleType('model_mappings')
|
||||
mm.MODEL_TO_TEMPLATE_MAPPER = {{}}
|
||||
sys.modules['model_mappings'] = mm
|
||||
source = open({str(before_file)!r}).read()
|
||||
source = open({str(before_file)!r}, encoding = "utf-8").read()
|
||||
source = source.replace('from .format_detection import', 'from format_detection import')
|
||||
source = source.replace('from .model_mappings import', 'from model_mappings import')
|
||||
exec(source)
|
||||
|
|
@ -215,7 +215,7 @@ class TestBeforeAfterImportChain:
|
|||
loggers = types.ModuleType('loggers')
|
||||
loggers.get_logger = lambda n: None
|
||||
sys.modules['loggers'] = loggers
|
||||
exec(open({str(before_file)!r}).read())
|
||||
exec(open({str(before_file)!r}, encoding = "utf-8").read())
|
||||
""")
|
||||
result = _run_in_sandbox(no_torch_venv, code)
|
||||
assert result.returncode != 0, "BEFORE data_collators.py should crash without torch"
|
||||
|
|
@ -284,7 +284,7 @@ class TestBeforeAfterImportChain:
|
|||
it = types.ModuleType('iterable')
|
||||
it.is_streaming_dataset = lambda *a, **k: False
|
||||
sys.modules['iterable'] = it
|
||||
source = open({str(CHAT_TEMPLATES)!r}).read()
|
||||
source = open({str(CHAT_TEMPLATES)!r}, encoding = "utf-8").read()
|
||||
source = source.replace('from .format_detection import', 'from format_detection import')
|
||||
source = source.replace('from .model_mappings import', 'from model_mappings import')
|
||||
source = source.replace('from .iterable import', 'from iterable import')
|
||||
|
|
@ -304,7 +304,7 @@ class TestBeforeAfterImportChain:
|
|||
loggers = types.ModuleType('loggers')
|
||||
loggers.get_logger = lambda n: None
|
||||
sys.modules['loggers'] = loggers
|
||||
exec(open({str(DATA_COLLATORS)!r}).read())
|
||||
exec(open({str(DATA_COLLATORS)!r}, encoding = "utf-8").read())
|
||||
print("OK")
|
||||
""")
|
||||
result = _run_in_sandbox(no_torch_venv, code)
|
||||
|
|
@ -382,7 +382,7 @@ class TestDataclassInstantiation:
|
|||
loggers = types.ModuleType('loggers')
|
||||
loggers.get_logger = lambda n: None
|
||||
sys.modules['loggers'] = loggers
|
||||
exec(open({str(DATA_COLLATORS)!r}).read())
|
||||
exec(open({str(DATA_COLLATORS)!r}, encoding = "utf-8").read())
|
||||
obj = DataCollatorSpeechSeq2SeqWithPadding(processor=None)
|
||||
assert obj.processor is None
|
||||
print("OK")
|
||||
|
|
@ -397,7 +397,7 @@ class TestDataclassInstantiation:
|
|||
loggers = types.ModuleType('loggers')
|
||||
loggers.get_logger = lambda n: None
|
||||
sys.modules['loggers'] = loggers
|
||||
exec(open({str(DATA_COLLATORS)!r}).read())
|
||||
exec(open({str(DATA_COLLATORS)!r}, encoding = "utf-8").read())
|
||||
obj = DeepSeekOCRDataCollator(processor=None)
|
||||
assert obj.processor is None
|
||||
assert obj.max_length == 2048
|
||||
|
|
@ -414,7 +414,7 @@ class TestDataclassInstantiation:
|
|||
loggers = types.ModuleType('loggers')
|
||||
loggers.get_logger = lambda n: None
|
||||
sys.modules['loggers'] = loggers
|
||||
exec(open({str(DATA_COLLATORS)!r}).read())
|
||||
exec(open({str(DATA_COLLATORS)!r}, encoding = "utf-8").read())
|
||||
obj = VLMDataCollator(processor=None)
|
||||
assert obj.processor is None
|
||||
assert obj.max_length == 2048
|
||||
|
|
@ -441,7 +441,7 @@ class TestDataclassInstantiation:
|
|||
it.is_streaming_dataset = lambda *a, **k: False
|
||||
sys.modules['iterable'] = it
|
||||
ns = {{}}
|
||||
source = open({str(CHAT_TEMPLATES)!r}).read()
|
||||
source = open({str(CHAT_TEMPLATES)!r}, encoding = "utf-8").read()
|
||||
source = source.replace('from .format_detection import', 'from format_detection import')
|
||||
source = source.replace('from .model_mappings import', 'from model_mappings import')
|
||||
source = source.replace('from .iterable import', 'from iterable import')
|
||||
|
|
@ -473,7 +473,7 @@ class TestEdgeCasesBrokenTorch:
|
|||
code = textwrap.dedent(f"""\
|
||||
import sys
|
||||
sys.path.insert(0, {str(sandbox_dir)!r})
|
||||
exec(open({str(sandbox_dir / 'data_collators.py')!r}).read())
|
||||
exec(open({str(sandbox_dir / 'data_collators.py')!r}, encoding = "utf-8").read())
|
||||
obj = DataCollatorSpeechSeq2SeqWithPadding(processor=None)
|
||||
print("OK: data_collators works despite broken torch on sys.path")
|
||||
""")
|
||||
|
|
@ -495,7 +495,7 @@ class TestEdgeCasesBrokenTorch:
|
|||
code = textwrap.dedent(f"""\
|
||||
import sys
|
||||
sys.path.insert(0, {str(sandbox_dir)!r})
|
||||
source = open({str(HARDWARE_PY)!r}).read()
|
||||
source = open({str(HARDWARE_PY)!r}, encoding = "utf-8").read()
|
||||
ns = {{'__name__': '__test__'}}
|
||||
exec(source, ns)
|
||||
result = ns['detect_hardware']()
|
||||
|
|
@ -530,7 +530,7 @@ class TestEdgeCasesBrokenTorch:
|
|||
code = textwrap.dedent(f"""\
|
||||
import sys
|
||||
sys.path.insert(0, {str(sandbox_dir)!r})
|
||||
source = open({str(HARDWARE_PY)!r}).read()
|
||||
source = open({str(HARDWARE_PY)!r}, encoding = "utf-8").read()
|
||||
ns = {{'__name__': '__test__'}}
|
||||
exec(source, ns)
|
||||
result = ns['detect_hardware']()
|
||||
|
|
@ -559,7 +559,7 @@ class TestEdgeCasesBrokenTorch:
|
|||
sys.modules['iterable'] = it
|
||||
|
||||
ns = {{}}
|
||||
source = open({str(CHAT_TEMPLATES)!r}).read()
|
||||
source = open({str(CHAT_TEMPLATES)!r}, encoding = "utf-8").read()
|
||||
source = source.replace('from .format_detection import', 'from format_detection import')
|
||||
source = source.replace('from .model_mappings import', 'from model_mappings import')
|
||||
source = source.replace('from .iterable import', 'from iterable import')
|
||||
|
|
@ -604,7 +604,7 @@ class TestHardwareDetectionNoTorch:
|
|||
code = textwrap.dedent(f"""\
|
||||
import sys
|
||||
sys.path.insert(0, {str(sandbox_dir)!r})
|
||||
source = open({str(HARDWARE_PY)!r}).read()
|
||||
source = open({str(HARDWARE_PY)!r}, encoding = "utf-8").read()
|
||||
ns = {{'__name__': '__test__'}}
|
||||
exec(source, ns)
|
||||
device = ns['detect_hardware']()
|
||||
|
|
@ -624,7 +624,7 @@ class TestHardwareDetectionNoTorch:
|
|||
code = textwrap.dedent(f"""\
|
||||
import sys
|
||||
sys.path.insert(0, {str(sandbox_dir)!r})
|
||||
source = open({str(HARDWARE_PY)!r}).read()
|
||||
source = open({str(HARDWARE_PY)!r}, encoding = "utf-8").read()
|
||||
ns = {{'__name__': '__test__'}}
|
||||
exec(source, ns)
|
||||
versions = ns['get_package_versions']()
|
||||
|
|
@ -651,7 +651,7 @@ class TestHardwareDetectionNoTorch:
|
|||
code = textwrap.dedent(f"""\
|
||||
import sys
|
||||
sys.path.insert(0, {str(sandbox_dir)!r})
|
||||
source = open({str(hw_sandbox / 'hardware.py')!r}).read()
|
||||
source = open({str(hw_sandbox / 'hardware.py')!r}, encoding = "utf-8").read()
|
||||
ns = {{'__name__': '__test__'}}
|
||||
exec(source, ns)
|
||||
assert callable(ns['detect_hardware'])
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ UTILS_PATH = REPO_ROOT / "unsloth" / "models" / "_utils.py"
|
|||
|
||||
|
||||
def _source(path):
|
||||
return path.read_text()
|
||||
return path.read_text(encoding = "utf-8")
|
||||
|
||||
|
||||
def _class_method(tree, class_name, method_name):
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ LLAMA_PATH = REPO_ROOT / "unsloth" / "models" / "llama.py"
|
|||
|
||||
|
||||
def _source(path):
|
||||
return path.read_text()
|
||||
return path.read_text(encoding = "utf-8")
|
||||
|
||||
|
||||
def _class_method(tree, class_name, method_name):
|
||||
|
|
|
|||
|
|
@ -17,13 +17,13 @@ def _find_geteuid_guard(tree: ast.AST):
|
|||
|
||||
|
||||
def test_gpu_init_has_geteuid_guard():
|
||||
tree = ast.parse(GPU_INIT.read_text())
|
||||
tree = ast.parse(GPU_INIT.read_text(encoding = "utf-8"))
|
||||
guard = _find_geteuid_guard(tree)
|
||||
assert guard is not None, "_gpu_init.py must guard ldconfig recovery on os.geteuid()"
|
||||
|
||||
|
||||
def test_ldconfig_calls_only_inside_geteuid_guard():
|
||||
src = GPU_INIT.read_text()
|
||||
src = GPU_INIT.read_text(encoding = "utf-8")
|
||||
tree = ast.parse(src)
|
||||
guard = _find_geteuid_guard(tree)
|
||||
assert guard is not None
|
||||
|
|
@ -39,6 +39,6 @@ def test_ldconfig_calls_only_inside_geteuid_guard():
|
|||
|
||||
|
||||
def test_non_root_branch_warns_when_bnb_present():
|
||||
src = GPU_INIT.read_text()
|
||||
src = GPU_INIT.read_text(encoding = "utf-8")
|
||||
assert "elif bnb is not None" in src
|
||||
assert "sudo ldconfig" in src
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ SOURCE_PATH = os.path.join(REPO_ROOT, "unsloth", "models", "rl_replacements.py")
|
|||
|
||||
|
||||
def _read_source() -> str:
|
||||
with open(SOURCE_PATH, "r") as fh:
|
||||
with open(SOURCE_PATH, "r", encoding = "utf-8") as fh:
|
||||
return fh.read()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ RL_PATH = os.path.join(REPO_ROOT, "unsloth", "models", "rl_replacements.py")
|
|||
|
||||
|
||||
def _load_orpo_rewriter(name = "orpo_trainer_text_tokenizer"):
|
||||
src = open(RL_PATH).read()
|
||||
src = open(RL_PATH, encoding = "utf-8").read()
|
||||
tree = ast.parse(src)
|
||||
ns = {"re": re}
|
||||
# Materialise sibling module-level _-prefixed assignments the rewriter may reference.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ WANTED = {
|
|||
|
||||
def _load_pad_helpers():
|
||||
"""Exec only the pad-token helpers with a stub logger (no heavy imports)."""
|
||||
tree = ast.parse(open(TOK_PATH).read())
|
||||
tree = ast.parse(open(TOK_PATH, encoding = "utf-8").read())
|
||||
nodes = []
|
||||
for node in tree.body:
|
||||
if isinstance(node, ast.Assign):
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ class TestDataCollatorsNoTorchVenv:
|
|||
loggers = types.ModuleType('loggers')
|
||||
loggers.get_logger = lambda n: None
|
||||
sys.modules['loggers'] = loggers
|
||||
exec(open({str(DATA_COLLATORS)!r}).read())
|
||||
exec(open({str(DATA_COLLATORS)!r}, encoding = "utf-8").read())
|
||||
print("OK: exec succeeded")
|
||||
""")
|
||||
result = subprocess.run(
|
||||
|
|
@ -168,7 +168,7 @@ class TestDataCollatorsNoTorchVenv:
|
|||
loggers = types.ModuleType('loggers')
|
||||
loggers.get_logger = lambda n: None
|
||||
sys.modules['loggers'] = loggers
|
||||
exec(open({str(DATA_COLLATORS)!r}).read())
|
||||
exec(open({str(DATA_COLLATORS)!r}, encoding = "utf-8").read())
|
||||
obj = DataCollatorSpeechSeq2SeqWithPadding(processor=None)
|
||||
assert obj.processor is None, "processor should be None"
|
||||
print("OK: DataCollatorSpeechSeq2SeqWithPadding instantiated")
|
||||
|
|
@ -190,7 +190,7 @@ class TestDataCollatorsNoTorchVenv:
|
|||
loggers = types.ModuleType('loggers')
|
||||
loggers.get_logger = lambda n: None
|
||||
sys.modules['loggers'] = loggers
|
||||
exec(open({str(DATA_COLLATORS)!r}).read())
|
||||
exec(open({str(DATA_COLLATORS)!r}, encoding = "utf-8").read())
|
||||
obj = DeepSeekOCRDataCollator(processor=None)
|
||||
assert obj.processor is None, "processor should be None"
|
||||
assert obj.max_length == 2048, "default max_length should be 2048"
|
||||
|
|
@ -212,7 +212,7 @@ class TestDataCollatorsNoTorchVenv:
|
|||
loggers = types.ModuleType('loggers')
|
||||
loggers.get_logger = lambda n: None
|
||||
sys.modules['loggers'] = loggers
|
||||
exec(open({str(DATA_COLLATORS)!r}).read())
|
||||
exec(open({str(DATA_COLLATORS)!r}, encoding = "utf-8").read())
|
||||
obj = VLMDataCollator(processor=None)
|
||||
assert obj.processor is None
|
||||
assert obj.mask_input_tokens is True, "default mask_input_tokens should be True"
|
||||
|
|
@ -259,7 +259,7 @@ class TestChatTemplatesNoTorchVenv:
|
|||
sys.modules['iterable'] = iterable
|
||||
|
||||
# Read and transform the source: replace relative imports with absolute
|
||||
source = open({str(CHAT_TEMPLATES)!r}).read()
|
||||
source = open({str(CHAT_TEMPLATES)!r}, encoding = "utf-8").read()
|
||||
source = source.replace('from .format_detection import', 'from format_detection import')
|
||||
source = source.replace('from .model_mappings import', 'from model_mappings import')
|
||||
source = source.replace('from .iterable import', 'from iterable import')
|
||||
|
|
@ -305,7 +305,7 @@ class TestChatTemplatesNoTorchVenv:
|
|||
sys.modules['iterable'] = iterable
|
||||
|
||||
ns = {{}}
|
||||
source = open({str(CHAT_TEMPLATES)!r}).read()
|
||||
source = open({str(CHAT_TEMPLATES)!r}, encoding = "utf-8").read()
|
||||
source = source.replace('from .format_detection import', 'from format_detection import')
|
||||
source = source.replace('from .model_mappings import', 'from model_mappings import')
|
||||
source = source.replace('from .iterable import', 'from iterable import')
|
||||
|
|
@ -402,7 +402,7 @@ class TestFormatConversionNoTorchVenv:
|
|||
sys.modules['utils.hardware'] = hardware_mod
|
||||
|
||||
# Read and exec format_conversion.py
|
||||
source = open({str(FORMAT_CONVERSION)!r}).read()
|
||||
source = open({str(FORMAT_CONVERSION)!r}, encoding = "utf-8").read()
|
||||
source = source.replace('from .format_detection import', 'from format_detection import')
|
||||
source = source.replace('from .iterable import', 'from iterable import')
|
||||
ns = {{'__name__': '__test__'}}
|
||||
|
|
@ -463,7 +463,7 @@ class TestFormatConversionNoTorchVenv:
|
|||
sys.modules['utils'] = utils_mod
|
||||
sys.modules['utils.hardware'] = hardware_mod
|
||||
|
||||
source = open({str(FORMAT_CONVERSION)!r}).read()
|
||||
source = open({str(FORMAT_CONVERSION)!r}, encoding = "utf-8").read()
|
||||
source = source.replace('from .format_detection import', 'from format_detection import')
|
||||
source = source.replace('from .iterable import', 'from iterable import')
|
||||
ns = {{'__name__': '__test__'}}
|
||||
|
|
@ -517,7 +517,7 @@ class TestNegativeControls:
|
|||
loggers = types.ModuleType('loggers')
|
||||
loggers.get_logger = lambda n: None
|
||||
sys.modules['loggers'] = loggers
|
||||
exec(open({temp_file!r}).read())
|
||||
exec(open({temp_file!r}, encoding = "utf-8").read())
|
||||
""")
|
||||
result = subprocess.run(
|
||||
[no_torch_venv, "-c", code],
|
||||
|
|
|
|||
|
|
@ -88,11 +88,21 @@ class TestStructuralTorchConstraint:
|
|||
"""$TORCH_CONSTRAINT must appear in a uv pip install line."""
|
||||
assert '"$TORCH_CONSTRAINT"' in self._sh
|
||||
|
||||
def test_hardcoded_torch_constraint_only_once(self):
|
||||
"""The hard-coded torch>=2.4,<2.11.0 string should appear exactly once
|
||||
in install.sh (the default assignment), not in pip install lines."""
|
||||
count = self._sh.count('"torch>=2.4,<2.11.0"')
|
||||
assert count == 1, f"Expected 1, found {count}"
|
||||
def test_hardcoded_torch_constraint_only_on_assignments(self):
|
||||
"""The hard-coded torch>=2.4,<2.11.0 string must only appear on
|
||||
TORCH_CONSTRAINT= assignment lines, never on a pip/uv install line
|
||||
(those must reference $TORCH_CONSTRAINT). Two assignments are expected:
|
||||
the default, and the gfx906 (MI50) reroute that restores the default
|
||||
<2.11 window after the rocm7.2 floor bump raised it to 2.11."""
|
||||
hits = [ln for ln in self._sh.splitlines() if '"torch>=2.4,<2.11.0"' in ln]
|
||||
assert hits, "default constraint literal missing from install.sh"
|
||||
for ln in hits:
|
||||
assert (
|
||||
"TORCH_CONSTRAINT=" in ln
|
||||
), f"torch>=2.4,<2.11.0 hardcoded off a TORCH_CONSTRAINT= assignment: {ln.strip()!r}"
|
||||
assert (
|
||||
"pip install" not in ln
|
||||
), f"torch>=2.4,<2.11.0 hardcoded on a pip install line: {ln.strip()!r}"
|
||||
|
||||
def test_tightening_guarded_by_skip_torch(self):
|
||||
"""The block must check SKIP_TORCH=false."""
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ RL_PY = Path(__file__).resolve().parents[2] / "unsloth" / "models" / "rl.py"
|
|||
|
||||
|
||||
def _extract_mixed_precision_code() -> str:
|
||||
lines = RL_PY.read_text().split("\n")
|
||||
lines = RL_PY.read_text(encoding = "utf-8").split("\n")
|
||||
try:
|
||||
start = next(i for i, l in enumerate(lines) if "mixed_precision = (" in l)
|
||||
except StopIteration:
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ def test_vlm_lora_regex_respects_language_only_with_explicit_targets():
|
|||
|
||||
|
||||
def test_fast_vision_model_wraps_explicit_targets_when_layer_filters_are_used():
|
||||
source = Path("unsloth/models/vision.py").read_text()
|
||||
source = Path("unsloth/models/vision.py").read_text(encoding = "utf-8")
|
||||
|
||||
assert "target_modules = get_peft_regex(" in source
|
||||
assert "target_modules = list(target_modules)" in source
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue