fix(release): strip+filter bundle + report size (#13)

* ci: opt JavaScript actions into Node 24 runtime

GH deprecates Node 20 for JavaScript actions on 2026-09-16. The
deprecation warning surfaces on every run right now. Setting
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true at workflow level makes
actions/checkout, actions/setup-*, astral-sh/setup-uv, and
oven-sh/setup-bun all run on Node 24 without bumping action versions.

This is a runtime override only — our own test script still pins
Node 22 via actions/setup-node@v4 (required for
--experimental-strip-types).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(release): strip symbols + filter CUDA/CUDA-provider binaries, report size

Previous slim pass (PR #11, CPU-only torch + module excludes) still left
the frozen backend above GH Releases' 2 GB per-asset cap. Two more levers:

1. strip=True on EXE + COLLECT. Strips debug symbols from ELF/Mach-O
   native libraries. libtorch_cpu.so and friends drop ~25-30%. No-op on
   Windows (MSVC stores symbols in separate .pdb files).

2. optimize=2 in Analysis. Compiles embedded bytecode with -OO:
   docstrings + assertions removed. ~50-80 MB off the PYZ archive.

3. Post-hoc binary filter after collect_all. Even with nvidia wheels
   excluded as Python modules, collect_all('torch')/('onnxruntime') can
   still pull the CUDA-runtime shared libs via their linker hints.
   Pattern-match them out of a.binaries before PYZ.

4. Log bundle size after freeze so CI runs can be compared without
   downloading artifacts.

If this round still overshoots 2 GB, the next step is splitting the
payload (thin installer + post-install download of the Python bundle).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Palash Debnath
2026-04-23 03:01:10 +05:30
committed by GitHub
co-authored by Claude Opus 4.7
parent c3aa2e4533
commit d29db18214
2 changed files with 42 additions and 3 deletions
+7
View File
@@ -192,6 +192,13 @@ jobs:
uv run pyinstaller backend.spec --noconfirm --clean
echo "Backend frozen at dist/omnivoice-backend/"
ls dist/omnivoice-backend/ | head
# Report total bundle size so we can eyeball CI against GH's 2 GB
# per-asset cap on Releases uploads.
if [[ "$RUNNER_OS" == "Windows" ]]; then
powershell -Command "(Get-ChildItem -Recurse dist/omnivoice-backend | Measure-Object -Property Length -Sum).Sum / 1MB"
else
du -sh dist/omnivoice-backend
fi
# ── Frontend build ─────────────────────────────────────────────────
- name: Install frontend deps
+35 -3
View File
@@ -179,8 +179,37 @@ a = Analysis(
'numpy.tests', 'numpy.testing.tests',
],
noarchive=False,
optimize=0,
# optimize=2 compiles the embedded stdlib + site-packages with -OO,
# stripping assert statements + docstrings. Saves ~50-80 MB on a bundle
# this size. Runtime impact is negligible because we never inspect
# docstrings at runtime.
optimize=2,
)
# Post-hoc binary filter: even on CPU-only torch wheels, collect_all pulls
# a few large libraries the desktop runtime never touches. Drop them by
# substring match on the archive name — PyInstaller re-runs when any of
# these return False, so be precise (no matching "cuda" would eat too much).
_DROP_BINARY_PATTERNS = (
# nvidia wheels (already in excludes, but collect_all can still pull their
# .so/.dll via torch's linker hints)
'libcudart.', 'libcublas.', 'libcublasLt.', 'libcudnn',
'libcurand.', 'libcufft.', 'libcusolver.', 'libcusparse.',
'libnccl.', 'libnvToolsExt.', 'libnvrtc.', 'libnvjitlink.',
'cudart64_', 'cublas64_', 'cublasLt64_', 'cudnn64_',
'curand64_', 'cufft64_', 'cusolver64_', 'cusparse64_',
# torch training / JIT runtimes not used by inference.
'libtorch_cuda', 'torch_cuda.', 'torch_cuda_linalg.',
# onnxruntime CUDA provider (we use CPU provider only).
'onnxruntime_providers_cuda', 'onnxruntime_providers_tensorrt',
)
def _keep_binary(entry):
name = entry[0].lower()
return not any(pat.lower() in name for pat in _DROP_BINARY_PATTERNS)
a.binaries = [b for b in a.binaries if _keep_binary(b)]
pyz = PYZ(a.pure)
exe = EXE(
@@ -191,7 +220,10 @@ exe = EXE(
name='omnivoice-backend',
debug=False,
bootloader_ignore_signals=False,
strip=False,
# strip=True removes debug symbols from ELF/Mach-O binaries (no-op on
# Windows since MSVC doesn't emit symbols in the same way). Saves
# 10-30% on native libraries like libtorch_cpu.so (~300 MB → ~220 MB).
strip=True,
upx=False, # UPX often corrupts ML native libs — disabled.
console=True,
disable_windowed_traceback=False,
@@ -204,7 +236,7 @@ coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
strip=True,
upx=False,
upx_exclude=[],
name='omnivoice-backend',