Polish pass: fix syntax bug, scrub private IP, add tests/CI/packaging#1
Conversation
…ackaging - Fix SyntaxError in python/unified_ml.py (unquoted time.strftime format). - Strip private Tailscale IP from NPU_STATUS.md and the "musicgen venv" developer reference from vulkan/benchmark_comparison.py. - Harden GGUFLoader.close()/__del__ against partial construction (AttributeError when __init__ raises before mmap is set). - Remove unused imports/assignments flagged by ruff; replace torch-import availability probe with importlib.util.find_spec. - Add pure-logic pytest suite (14 tests): GGUF header/metadata/tensor parsing on a synthesized file + F32/Q8_0/Q4_0 dequant math, and the stdlib-only UnifiedML binary-discovery wrapper. No torch/HIP/Vulkan/ model weights are imported. - Add requirements.txt (numpy pinned; torch/kompute documented as optional), pyproject.toml (project metadata + ruff/pytest config), and a GitHub Actions CI workflow running ruff + pytest on Python 3.11/3.12. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Independent verification — verdict: SOLID ✅Cloned Lint — Tests — CI will be green on a clean GitHub runner. The workflow installs only Bug fixes verified against master:
Security/path scrub verified: repo-wide grep finds no Tailscale/RFC1918 IPs, no No overclaims in the PR body. The 'Not verified' section honestly scopes out HIP/Vulkan/torch runtime paths, which is correct — those need a GPU. The benchmark scripts and shaders were lint-only, as stated. Minor notes (non-blocking):
Clean, honest, and CI-green-able without hardware. Recommend merge. |
Full polish pass on the Python side of unified-ml. No behavior changes to the GPU/HIP/Vulkan paths — only bug fixes, hygiene, tests, and packaging.
What changed
Bug fixes (verified)
python/unified_ml.py— fixed a hardSyntaxError:time.strftime(%Y-%m-%d %H:%M:%S)was missing the quotes around the format string. The module did not even parse before this. Confirmed it nowpy_compiles.src/gguf_loader.py—close()/__del__raisedAttributeErrorwhen__init__failed early (e.g. missing file), because_mm/_fpwere never assigned. Now guarded withgetattr. A regression test covers the missing-file path.Security / path hygiene (verified)
NPU_STATUS.md(Host:line) — replaced with a generic node description.vulkan/benchmark_comparison.pydocstring./home/...paths.Lint (verified)
ruff check .passes (was failing: the syntax error plus severalF401/F841).sys,os,json,typing.List,typing.Optional) and unused warmup/timed loop assignments.try: import torchavailability probe withimportlib.util.find_spec("torch")(no side-effect import).[tool.ruff]config topyproject.toml. Import-sorting (I) deliberately left out to avoid churning untouched import blocks.Tests (verified — 14 passing)
tests/test_gguf_loader.py: builds a minimal valid GGUF v3 file in a tmp dir and round-trips header/metadata/tensor-info parsing, the 32-byte data-section alignment rule, array-metadata parsing, and error paths (bad magic, missing file, missing tensor). Plus bit-exactF32/Q8_0/Q4_0dequant math against hand-constructed inputs (scalar vs vectorized agreement).tests/test_unified_ml.py: covers the stdlib-only subprocess wrapper —DeviceInforepr, binary discovery, and error handling on missing binaries (uses fake executables, runs nothing GPU-related).numpy(a light dep) is used.Packaging + CI (added)
requirements.txt— pinsnumpy(the only always-required runtime dep);torchandkomputedocumented as optional, install-the-build-that-matches-your-GPU extras.pyproject.toml— project metadata, optional-dependency extras, ruff + pytest config..github/workflows/ci.yml— runsruff check .andpytest -q testson Python 3.11/3.12, installing only ruff/pytest/numpy. Scoped to the pure-logic tests so it stays green without a GPU or model weights.Not verified (out of scope / no hardware)
src/*.hip), Vulkan shaders, and thetorch/komputebenchmark code paths were not executed — they require ROCm, a GPU, Kompute, and/or model weights that aren't available in this environment. Those files were read and lint-checked but their runtime behavior is unchanged and unexercised.🤖 Generated with Claude Code