chore: import upstream snapshot with attribution
Lint / lint (push) Has been cancelled
Build Docs / Deploy Docs (push) Has been cancelled
Windows CI / Windows (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:23:58 +08:00
commit 770d92cb1f
694 changed files with 114634 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
import json
import tempfile
from pathlib import Path
import pytest
from mlc_llm.support import logging
from mlc_llm.support.auto_config import detect_config
logging.enable_logging()
# test category "unittest"
pytestmark = [pytest.mark.unittest]
def _create_json_file(json_path, data):
with open(json_path, "w", encoding="utf-8") as i_f:
json.dump(data, i_f)
def test_detect_config():
with tempfile.TemporaryDirectory() as tmpdir:
base_path = Path(tmpdir)
config_json_path = base_path / "config.json"
_create_json_file(config_json_path, {})
assert detect_config(base_path) == config_json_path
assert detect_config(config_json_path) == config_json_path
def test_detect_config_fail():
with pytest.raises(ValueError):
detect_config(Path("do/not/exist"))
with tempfile.TemporaryDirectory() as tmpdir:
base_path = Path(tmpdir)
with pytest.raises(ValueError):
assert detect_config(base_path)
if __name__ == "__main__":
test_detect_config()
test_detect_config_fail()
+37
View File
@@ -0,0 +1,37 @@
import pytest
from tvm.target import Target
from mlc_llm.support.auto_target import _apply_webgpu_subgroups
# test category "unittest"
pytestmark = [pytest.mark.unittest]
def test_apply_webgpu_subgroups_enables_webgpu_target():
target = Target("webgpu")
updated = _apply_webgpu_subgroups(target, True)
assert updated is not target
assert dict(target.export())["supports_subgroups"] is False
assert dict(updated.export())["supports_subgroups"] is True
def test_apply_webgpu_subgroups_non_webgpu_target_is_unchanged():
target = Target("llvm")
updated = _apply_webgpu_subgroups(target, True)
assert updated is target
assert dict(updated.export()) == dict(target.export())
@pytest.mark.parametrize("target_kind", ["webgpu", "llvm"])
@pytest.mark.parametrize("enable_subgroups", [False, None])
def test_apply_webgpu_subgroups_disabled_is_unchanged(target_kind, enable_subgroups):
target = Target(target_kind)
updated = _apply_webgpu_subgroups(target, enable_subgroups)
assert updated is target
assert dict(updated.export()) == dict(target.export())
+150
View File
@@ -0,0 +1,150 @@
import json
import os
import tempfile
from pathlib import Path
import pytest
from mlc_llm.support import logging
from mlc_llm.support.auto_weight import detect_weight
logging.enable_logging()
# test category "unittest"
pytestmark = [pytest.mark.unittest]
def _create_json_file(json_path, data):
with open(json_path, "w", encoding="utf-8") as i_f:
json.dump(data, i_f)
@pytest.mark.parametrize(
"weight_format, index_filename, result",
[
("huggingface-torch", "pytorch_model.bin.index.json", "huggingface-torch"),
(
"huggingface-safetensor",
"model.safetensors.index.json",
"huggingface-safetensor",
),
("auto", "pytorch_model.bin.index.json", "huggingface-torch"),
("auto", "model.safetensors.index.json", "huggingface-safetensor"),
],
)
def test_detect_weight(weight_format, index_filename, result):
with tempfile.TemporaryDirectory() as tmpdir:
base_path = Path(tmpdir)
if index_filename is not None:
weight_index_file = base_path / index_filename
_create_json_file(weight_index_file, {})
assert detect_weight(base_path, None, weight_format) == (
weight_index_file,
result,
)
@pytest.mark.parametrize(
"weight_format, index_filename, result",
[
("huggingface-torch", "pytorch_model.bin.index.json", "huggingface-torch"),
(
"huggingface-safetensor",
"model.safetensors.index.json",
"huggingface-safetensor",
),
("auto", "pytorch_model.bin.index.json", "huggingface-torch"),
("auto", "model.safetensors.index.json", "huggingface-safetensor"),
],
)
def test_detect_weight_in_config_json(weight_format, index_filename, result):
with (
tempfile.TemporaryDirectory() as config_dir,
tempfile.TemporaryDirectory() as weight_dir,
):
config_path = Path(config_dir)
weight_path = Path(weight_dir)
config_json_path = config_path / "config.json"
_create_json_file(config_json_path, {"weight_path": weight_dir})
if index_filename is not None:
weight_index_file = weight_path / index_filename
_create_json_file(weight_index_file, {})
assert detect_weight(None, config_json_path, weight_format) == (
weight_index_file,
result,
)
@pytest.mark.parametrize(
"weight_format, index_filename, result",
[
("huggingface-torch", "pytorch_model.bin.index.json", "huggingface-torch"),
(
"huggingface-safetensor",
"model.safetensors.index.json",
"huggingface-safetensor",
),
("auto", "pytorch_model.bin.index.json", "huggingface-torch"),
("auto", "model.safetensors.index.json", "huggingface-safetensor"),
],
)
def test_detect_weight_same_dir_config_json(weight_format, index_filename, result):
with tempfile.TemporaryDirectory() as tmpdir:
base_path = Path(tmpdir)
config_json_path = base_path / "config.json"
_create_json_file(config_json_path, {})
if index_filename is not None:
weight_index_file = Path(os.path.join(tmpdir, index_filename))
_create_json_file(weight_index_file, {})
assert detect_weight(None, config_json_path, weight_format) == (
weight_index_file,
result,
)
def test_find_weight_fail():
with tempfile.TemporaryDirectory() as tmpdir:
base_path = Path(tmpdir)
with pytest.raises(ValueError):
detect_weight(Path("do/not/exist"), base_path, "awq")
with pytest.raises(AssertionError):
detect_weight(None, Path("do/not/exist"), "awq")
if __name__ == "__main__":
test_detect_weight("huggingface-torch", "pytorch_model.bin.index.json", "huggingface-torch")
test_detect_weight(
"huggingface-safetensor",
"model.safetensors.index.json",
"huggingface-safetensor",
)
test_detect_weight("auto", "pytorch_model.bin.index.json", "huggingface-torch")
test_detect_weight("auto", "model.safetensors.index.json", "huggingface-safetensor")
test_detect_weight_in_config_json(
"huggingface-torch", "pytorch_model.bin.index.json", "huggingface-torch"
)
test_detect_weight_in_config_json(
"huggingface-safetensor",
"model.safetensors.index.json",
"huggingface-safetensor",
)
test_detect_weight_in_config_json("auto", "pytorch_model.bin.index.json", "huggingface-torch")
test_detect_weight_in_config_json(
"auto", "model.safetensors.index.json", "huggingface-safetensor"
)
test_detect_weight_same_dir_config_json(
"huggingface-torch", "pytorch_model.bin.index.json", "huggingface-torch"
)
test_detect_weight_same_dir_config_json(
"huggingface-safetensor",
"model.safetensors.index.json",
"huggingface-safetensor",
)
test_detect_weight_same_dir_config_json(
"auto", "pytorch_model.bin.index.json", "huggingface-torch"
)
test_detect_weight_same_dir_config_json(
"auto", "model.safetensors.index.json", "huggingface-safetensor"
)
test_find_weight_fail()
@@ -0,0 +1,69 @@
import json
import tempfile
from pathlib import Path
import pytest
from mlc_llm.cli import convert_weight as convert_weight_cli
pytestmark = [pytest.mark.unittest]
def test_convert_weight_cli_passes_lora_adapter(monkeypatch):
with tempfile.TemporaryDirectory() as tmp_dir:
temp_path = Path(tmp_dir)
config_path = temp_path / "config.json"
source_dir = temp_path / "source"
source_dir.mkdir(parents=True, exist_ok=True)
source_index = source_dir / "pytorch_model.bin.index.json"
adapter_dir = temp_path / "adapter"
adapter_dir.mkdir(parents=True, exist_ok=True)
output_dir = temp_path / "output"
config_path.write_text(json.dumps({}), encoding="utf-8")
source_index.write_text(json.dumps({"weight_map": {}}), encoding="utf-8")
def _fake_detect_device(device):
return device
def _fake_detect_weight(_weight_path, _config_json_path, _weight_format):
return source_index, "huggingface-torch"
def _fake_detect_model_type(_model_type, _config):
return "dummy"
monkeypatch.setattr(convert_weight_cli, "detect_config", Path)
monkeypatch.setattr(convert_weight_cli, "detect_device", _fake_detect_device)
monkeypatch.setattr(convert_weight_cli, "detect_weight", _fake_detect_weight)
monkeypatch.setattr(convert_weight_cli, "detect_model_type", _fake_detect_model_type)
monkeypatch.setattr(convert_weight_cli, "MODELS", {"dummy": object()})
monkeypatch.setattr(convert_weight_cli, "QUANTIZATION", {"q0f16": object()})
call_args = {}
def _fake_convert_weight(**kwargs):
call_args.update(kwargs)
monkeypatch.setattr(convert_weight_cli, "convert_weight", _fake_convert_weight)
convert_weight_cli.main(
[
str(config_path),
"--quantization",
"q0f16",
"--model-type",
"dummy",
"--source",
str(source_dir),
"--source-format",
"auto",
"--output",
str(output_dir),
"--lora-adapter",
str(adapter_dir),
]
)
assert call_args["lora_adapter"] == adapter_dir
assert call_args["source"] == source_index
assert call_args["source_format"] == "huggingface-torch"
@@ -0,0 +1,108 @@
import contextlib
import json
import tempfile
from pathlib import Path
import pytest
from mlc_llm.interface import convert_weight as convert_weight_interface
pytestmark = [pytest.mark.unittest]
def test_resolve_base_model_dir():
with tempfile.TemporaryDirectory() as tmp_dir:
temp_path = Path(tmp_dir)
model_dir = temp_path / "model"
model_dir.mkdir(parents=True, exist_ok=True)
source_file = model_dir / "pytorch_model.bin.index.json"
source_file.write_text(json.dumps({"weight_map": {}}), encoding="utf-8")
assert convert_weight_interface._resolve_base_model_dir(model_dir) == model_dir
assert convert_weight_interface._resolve_base_model_dir(source_file) == model_dir
def test_convert_weight_with_lora_uses_merged_source(monkeypatch):
with tempfile.TemporaryDirectory() as tmp_dir:
temp_path = Path(tmp_dir)
config_path = temp_path / "config.json"
config_path.write_text(json.dumps({}), encoding="utf-8")
source_dir = temp_path / "source"
source_dir.mkdir(parents=True, exist_ok=True)
source_file = source_dir / "pytorch_model.bin.index.json"
source_file.write_text(json.dumps({"weight_map": {}}), encoding="utf-8")
adapter_dir = temp_path / "adapter"
adapter_dir.mkdir(parents=True, exist_ok=True)
merged_dir = temp_path / "merged"
merged_dir.mkdir(parents=True, exist_ok=True)
merged_file = merged_dir / "pytorch_model.bin"
merged_file.write_bytes(b"")
captured = {}
@contextlib.contextmanager
def _fake_merge(base_source: Path, lora_adapter: Path):
captured["merge_base_source"] = base_source
captured["merge_lora_adapter"] = lora_adapter
yield merged_dir
def _fake_detect_weight(weight_path: Path, config_json_path: Path, weight_format: str):
captured["detect_weight_path"] = weight_path
captured["detect_weight_config"] = config_json_path
captured["detect_weight_format"] = weight_format
return merged_file, "huggingface-torch"
def _fake_convert_args(args):
captured["converted_args"] = args
monkeypatch.setattr(
convert_weight_interface, "_merge_lora_adapter_with_base_model", _fake_merge
)
monkeypatch.setattr(convert_weight_interface, "detect_weight", _fake_detect_weight)
monkeypatch.setattr(convert_weight_interface, "_convert_args", _fake_convert_args)
monkeypatch.setattr(convert_weight_interface.ConversionArgs, "display", lambda self: None)
convert_weight_interface.convert_weight(
config=config_path,
quantization=object(),
model=type("DummyModel", (), {"name": "dummy"})(),
device=object(),
source=source_file,
source_format="huggingface-safetensor",
output=temp_path / "output",
lora_adapter=adapter_dir,
)
converted_args = captured["converted_args"]
assert captured["merge_base_source"] == source_file
assert captured["merge_lora_adapter"] == adapter_dir
assert captured["detect_weight_path"] == merged_dir
assert captured["detect_weight_config"] == config_path
assert captured["detect_weight_format"] == "auto"
assert converted_args.source == merged_file
assert converted_args.source_format == "huggingface-torch"
assert converted_args.lora_adapter == adapter_dir
def test_convert_weight_with_lora_rejects_awq():
with tempfile.TemporaryDirectory() as tmp_dir:
temp_path = Path(tmp_dir)
config_path = temp_path / "config.json"
config_path.write_text(json.dumps({}), encoding="utf-8")
adapter_dir = temp_path / "adapter"
adapter_dir.mkdir(parents=True, exist_ok=True)
with pytest.raises(ValueError, match="only supports source formats"):
convert_weight_interface.convert_weight(
config=config_path,
quantization=object(),
model=type("DummyModel", (), {"name": "dummy"})(),
device=object(),
source=temp_path / "source",
source_format="awq",
output=temp_path / "output",
lora_adapter=adapter_dir,
)