Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ test/
# Student CLAP training (not needed in production)
student_clap/

# macOS and Linux standalone app: source trees (PyInstaller spec / nfpm config,
# vendored redis/pg binaries, assets) and build artifacts. None of it is used by
# the Linux container, so keep it out of the image.
# Native standalone app (macOS/Linux/Windows): the per-platform source trees
# (vendored redis/pg binaries, assets, nfpm config, runtime launchers), the shared
# PyInstaller spec + build tooling, and build artifacts. None of it is used by the
# Linux container, so keep it out of the image.
macos/
linux/
windows/
AudioMuse-AI.spec
scripts/standalone/
build/
dist/

Expand Down
85 changes: 4 additions & 81 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#
# The small native build inputs (redis-server, the unaccent/pg_trgm contrib
# modules) are built from source in this workflow (linux/vendor/*) rather than
# committed, then baked into the bundle by linux/AudioMuse-AI.spec.
# committed, then baked into the bundle by the shared AudioMuse-AI.spec.
#
# The ~5 GB of models are NOT in git. This workflow assembles ./model from the
# same GitHub releases the Dockerfile/macOS build use, INCLUDING the HuggingFace
Expand Down Expand Up @@ -146,87 +146,10 @@ jobs:
- name: Assemble ./model (mirrors the Dockerfile/macOS models stage)
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
mkdir -p model

echo "==> musicnn + CLAP text models (from ${MODEL_RELEASE})"
gh release download "$MODEL_RELEASE" -R "$GITHUB_REPOSITORY" -D model --clobber \
-p musicnn_embedding.onnx \
-p musicnn_prediction.onnx \
-p clap_text_model.onnx

echo "==> DCLAP audio model (from ${DCLAP_RELEASE} in the -DCLAP repo)"
gh release download "$DCLAP_RELEASE" -R NeptuneHub/AudioMuse-AI-DCLAP -D model --clobber \
-p model_epoch_36.onnx \
-p model_epoch_36.onnx.data

echo "==> HuggingFace cache (roberta/bert/bart) -- HF_HOME points at model/huggingface"
tmp_hf="$(mktemp -d)"
gh release download "$MODEL_RELEASE" -R "$GITHUB_REPOSITORY" -D "$tmp_hf" --clobber \
-p huggingface_models.tar.gz
mkdir -p model/huggingface
tar -xzf "$tmp_hf/huggingface_models.tar.gz" -C model/huggingface
rm -rf "$tmp_hf"

echo "==> Trim HF cache to just the roberta-base tokenizer (~1.4 GB saved)"
# The app's ONLY runtime HF dependency is the roberta-base *tokenizer*
# (tasks/clap_analyzer.py: AutoTokenizer.from_pretrained("roberta-base")).
# bert-base-uncased and bart-base are never loaded by the app, and a
# tokenizer does not need model weights. Dropping them keeps the release
# assets under the 2 GB GitHub limit without removing any model the app
# uses. (This prunes only this bundle copy -- the shared release tarball
# and the Docker build are unaffected.)
hf="model/huggingface/hub"
rm -rf "$hf/models--bert-base-uncased" "$hf/models--facebook--bart-base"
rb="$hf/models--roberta-base"
if [ -d "$rb" ]; then
find "$rb/blobs" -type f -size +10M -delete
find "$rb/snapshots" \( -name "model.safetensors" -o -name "pytorch_model.bin" \) -delete
du -sh "$rb"
fi

echo "==> lyrics bundles (whisper / silero / gte)"
tmp="$(mktemp -d)"
gh release download "$MODEL_RELEASE" -R "$GITHUB_REPOSITORY" -D "$tmp" --clobber \
-p lyrics_model_whisper.tar.gz \
-p lyrics_model_silero_vad.tar.gz \
-p lyrics_model_gte_vnni.tar.gz
for t in lyrics_model_whisper lyrics_model_silero_vad lyrics_model_gte_vnni; do
tar -xzf "$tmp/$t.tar.gz" -C model
done
rm -rf "$tmp"
run: python3 scripts/standalone/assemble_model.py

- name: Verify the assembled model/ is complete
run: |
set -euo pipefail
required=(
model/musicnn_embedding.onnx
model/musicnn_prediction.onnx
model/clap_text_model.onnx
model/model_epoch_36.onnx
model/model_epoch_36.onnx.data
model/huggingface/hub/models--roberta-base/snapshots
model/silero_vad.onnx
model/gte-multilingual-base-int8.onnx
model/whisper-small-onnx/encoder_model.onnx
model/whisper-small-onnx/decoder_model_merged.onnx
model/gte-multilingual-base/tokenizer.json
)
missing=0
for f in "${required[@]}"; do
# Flag a file that is missing OR a zero-byte/truncated download. The
# size test only applies to regular files (directory entries in the
# list pass on existence alone).
if [ ! -e "$f" ] || { [ -f "$f" ] && [ ! -s "$f" ]; }; then
echo "::error::Missing or empty: $f"; missing=1
fi
done
if [ -z "$(find model/huggingface/hub/models--roberta-base -name tokenizer.json -print -quit)" ]; then
echo "::error::roberta-base tokenizer.json missing after HF-cache prune"; missing=1
fi
[ "$missing" -eq 0 ] || { echo "::error::Refusing to build an incomplete bundle."; exit 1; }
du -sh model
run: python3 scripts/standalone/assemble_model.py --verify

- name: Build the packages (.deb + .rpm)
run: |
Expand All @@ -241,7 +164,7 @@ jobs:
else
PKG_VERSION="0.0.0"
fi
PKG_VERSION="$PKG_VERSION" bash linux/build.sh
PKG_VERSION="$PKG_VERSION" python scripts/standalone/build.py --platform linux
env:
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_REF_TYPE: ${{ github.ref_type }}
Expand Down
81 changes: 3 additions & 78 deletions .github/workflows/build-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,85 +104,10 @@ jobs:
- name: Assemble ./model (mirrors the Dockerfile models stage)
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
mkdir -p model

echo "==> musicnn + CLAP text models (from ${MODEL_RELEASE})"
gh release download "$MODEL_RELEASE" -R "$GITHUB_REPOSITORY" -D model --clobber \
-p musicnn_embedding.onnx \
-p musicnn_prediction.onnx \
-p clap_text_model.onnx

echo "==> DCLAP audio model (from ${DCLAP_RELEASE} in the -DCLAP repo)"
gh release download "$DCLAP_RELEASE" -R NeptuneHub/AudioMuse-AI-DCLAP -D model --clobber \
-p model_epoch_36.onnx \
-p model_epoch_36.onnx.data

echo "==> HuggingFace cache (roberta/bert/bart) — HF_HOME points at model/huggingface"
tmp_hf="$(mktemp -d)"
gh release download "$MODEL_RELEASE" -R "$GITHUB_REPOSITORY" -D "$tmp_hf" --clobber \
-p huggingface_models.tar.gz
mkdir -p model/huggingface
tar -xzf "$tmp_hf/huggingface_models.tar.gz" -C model/huggingface
rm -rf "$tmp_hf"

echo "==> Trim HF cache to just the roberta-base tokenizer (~1.4 GB saved)"
# The macOS app's ONLY runtime HF dependency is the roberta-base *tokenizer*
# (tasks/clap_analyzer.py: AutoTokenizer.from_pretrained("roberta-base")).
# bert-base-uncased and bart-base are never loaded by the app, and a tokenizer
# does not need model weights. Dropping them keeps the release zip under the
# 2 GB GitHub release-asset limit without removing any model the app uses.
# Note: this prunes only the macOS bundle copy — the shared release tarball
# and the Docker build are unaffected.
hf="model/huggingface/hub"
rm -rf "$hf/models--bert-base-uncased" "$hf/models--facebook--bart-base"
rb="$hf/models--roberta-base"
if [ -d "$rb" ]; then
# Drop the ~476 MB weight blob; AutoTokenizer reads only the tiny
# tokenizer.json/vocab.json/merges.txt/config files (all < 2 MB).
find "$rb/blobs" -type f -size +10M -delete
find "$rb/snapshots" \( -name "model.safetensors" -o -name "pytorch_model.bin" \) -delete
du -sh "$rb"
fi

echo "==> lyrics bundles (whisper / silero / gte) — downloaded then extracted into ./model"
tmp="$(mktemp -d)"
gh release download "$MODEL_RELEASE" -R "$GITHUB_REPOSITORY" -D "$tmp" --clobber \
-p lyrics_model_whisper.tar.gz \
-p lyrics_model_silero_vad.tar.gz \
-p lyrics_model_gte_vnni.tar.gz
for t in lyrics_model_whisper lyrics_model_silero_vad lyrics_model_gte_vnni; do
tar -xzf "$tmp/$t.tar.gz" -C model
done
rm -rf "$tmp"
run: python3 scripts/standalone/assemble_model.py

- name: Verify the assembled model/ is complete
run: |
set -euo pipefail
required=(
model/musicnn_embedding.onnx
model/musicnn_prediction.onnx
model/clap_text_model.onnx
model/model_epoch_36.onnx
model/model_epoch_36.onnx.data
model/huggingface/hub/models--roberta-base/snapshots
model/silero_vad.onnx
model/gte-multilingual-base-int8.onnx
model/whisper-small-onnx/encoder_model.onnx
model/whisper-small-onnx/decoder_model_merged.onnx
model/gte-multilingual-base/tokenizer.json
)
missing=0
for f in "${required[@]}"; do
if [ ! -e "$f" ]; then echo "::error::Missing or empty: $f"; missing=1; fi
done
# The roberta tokenizer files must survive the HF-cache prune above.
if [ -z "$(find model/huggingface/hub/models--roberta-base -name tokenizer.json -print -quit)" ]; then
echo "::error::roberta-base tokenizer.json missing after HF-cache prune"; missing=1
fi
[ "$missing" -eq 0 ] || { echo "::error::Refusing to build an incomplete bundle."; exit 1; }
du -sh model
run: python3 scripts/standalone/assemble_model.py --verify

- name: Install Python dependencies
run: |
Expand All @@ -196,7 +121,7 @@ jobs:
run: |
set -euo pipefail
source .venv-macos/bin/activate
bash macos/build.sh
python scripts/standalone/build.py --platform macos

- name: Upload zip as a workflow artifact
uses: actions/upload-artifact@v4
Expand Down
78 changes: 4 additions & 74 deletions .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#
# The small native build inputs (redis-server.exe, the unaccent/pg_trgm contrib
# modules) are built or downloaded in this workflow, then baked into the bundle
# by windows/AudioMuse-AI.spec.
# by the shared AudioMuse-AI.spec.
#
# The ~5 GB of models are NOT in git. This workflow assembles ./model from the
# same GitHub releases the Dockerfile/macOS/Linux builds use, INCLUDING the
Expand Down Expand Up @@ -103,92 +103,22 @@ jobs:
shell: powershell
env:
GH_TOKEN: ${{ github.token }}
run: |
New-Item -ItemType Directory -Force -Path model | Out-Null
$modelRelease = "$env:MODEL_RELEASE"
$dclapRelease = "$env:DCLAP_RELEASE"

Write-Host "==> musicnn + CLAP text models (from $modelRelease)"
gh release download $modelRelease -R $env:GITHUB_REPOSITORY -D model --clobber `
-p musicnn_embedding.onnx `
-p musicnn_prediction.onnx `
-p clap_text_model.onnx

Write-Host "==> DCLAP audio model (from $dclapRelease in the -DCLAP repo)"
gh release download $dclapRelease -R NeptuneHub/AudioMuse-AI-DCLAP -D model --clobber `
-p model_epoch_36.onnx `
-p model_epoch_36.onnx.data

Write-Host "==> HuggingFace cache (roberta/bert/bart)"
$tmp_hf = Join-Path $env:RUNNER_TEMP "hf_models"
New-Item -ItemType Directory -Force -Path $tmp_hf | Out-Null
gh release download $modelRelease -R $env:GITHUB_REPOSITORY -D $tmp_hf --clobber `
-p huggingface_models.tar.gz
New-Item -ItemType Directory -Force -Path model\huggingface | Out-Null
tar -xzf "$tmp_hf\huggingface_models.tar.gz" -C model\huggingface
if ($LASTEXITCODE -ne 0) { Write-Error "tar failed extracting huggingface models"; exit 1 }
Remove-Item -Recurse -Force $tmp_hf

Write-Host "==> Trim HF cache to just the roberta-base tokenizer (~1.4 GB saved)"
$hf = "model\huggingface\hub"
if (Test-Path "$hf\models--bert-base-uncased") { Remove-Item -Recurse -Force "$hf\models--bert-base-uncased" }
if (Test-Path "$hf\models--facebook--bart-base") { Remove-Item -Recurse -Force "$hf\models--facebook--bart-base" }
$rb = "$hf\models--roberta-base"
if (Test-Path $rb) {
Get-ChildItem -Recurse -File "$rb\blobs" | Where-Object { $_.Length -gt 10MB } | Remove-Item -Force
Get-ChildItem -Recurse "$rb\snapshots" -Include "model.safetensors","pytorch_model.bin" | Remove-Item -Force
}

Write-Host "==> lyrics bundles (whisper / silero / gte)"
$tmp = Join-Path $env:RUNNER_TEMP "lyrics_models"
New-Item -ItemType Directory -Force -Path $tmp | Out-Null
gh release download $modelRelease -R $env:GITHUB_REPOSITORY -D $tmp --clobber `
-p lyrics_model_whisper.tar.gz `
-p lyrics_model_silero_vad.tar.gz `
-p lyrics_model_gte_vnni.tar.gz
foreach ($t in @("lyrics_model_whisper", "lyrics_model_silero_vad", "lyrics_model_gte_vnni")) {
tar -xzf "$tmp\$t.tar.gz" -C model
if ($LASTEXITCODE -ne 0) { Write-Error "tar failed extracting $t"; exit 1 }
}
Remove-Item -Recurse -Force $tmp
run: python scripts/standalone/assemble_model.py

- name: Verify the assembled model/ is complete
shell: powershell
run: |
$required = @(
"model\musicnn_embedding.onnx",
"model\musicnn_prediction.onnx",
"model\clap_text_model.onnx",
"model\model_epoch_36.onnx",
"model\model_epoch_36.onnx.data",
"model\huggingface\hub\models--roberta-base\snapshots",
"model\silero_vad.onnx",
"model\gte-multilingual-base-int8.onnx",
"model\whisper-small-onnx\encoder_model.onnx",
"model\whisper-small-onnx\decoder_model_merged.onnx",
"model\gte-multilingual-base\tokenizer.json"
)
$missing = 0
foreach ($f in $required) {
if (-not (Test-Path $f)) {
Write-Error "Missing or empty: $f"
$missing = 1
}
}
if ($missing -ne 0) { Write-Error "Refusing to build an incomplete bundle."; exit 1 }
Write-Host "Model assembly verified."
run: python scripts/standalone/assemble_model.py --verify

- name: Build the bundle
shell: powershell
run: |
.venv-windows\Scripts\activate
if ($env:GITHUB_REF_TYPE -eq "tag") {
$ver = $env:GITHUB_REF_NAME -replace '^v', ''
} else {
$ver = "0.0.0"
}
$env:PKG_VERSION = $ver
cmd /c windows\build.bat
.venv-windows\Scripts\python scripts\standalone\build.py --platform windows
env:
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_REF_TYPE: ${{ github.ref_type }}
Expand Down
Loading
Loading