From e0980b06b1801b09c73a78e0d9e0a51d52adcf81 Mon Sep 17 00:00:00 2001 From: "push-app-to-main[bot]" <203845782+push-app-to-main[bot]@users.noreply.github.com> Date: Mon, 21 Sep 2026 17:16:05 +0200 Subject: [PATCH] AudioMuse-AI (#17415) * Add audiomuse-ai (ct) * Uncomment var_arm64 variable in audiomuse-ai.sh Uncomment var_arm64 variable assignment for user input. --------- Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com> Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com> --- ct/audiomuse-ai.sh | 81 +++++++++++ ct/headers/audiomuse-ai | 6 + install/audiomuse-ai-install.sh | 250 ++++++++++++++++++++++++++++++++ 3 files changed, 337 insertions(+) create mode 100644 ct/audiomuse-ai.sh create mode 100644 ct/headers/audiomuse-ai create mode 100644 install/audiomuse-ai-install.sh diff --git a/ct/audiomuse-ai.sh b/ct/audiomuse-ai.sh new file mode 100644 index 000000000..2efd1a7d3 --- /dev/null +++ b/ct/audiomuse-ai.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +_CS_DEFAULT_URL="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main" +_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func" +source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func") +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/NeptuneHub/AudioMuse-AI + +APP="AudioMuse-AI" +var_tags="${var_tags:-music;ai}" +var_cpu="${var_cpu:-4}" +var_ram="${var_ram:-8192}" +var_disk="${var_disk:-20}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +#var_arm64="${var_arm64:-no}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + if [[ ! -d /opt/audiomuse-ai ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if check_for_gh_release "audiomuse-ai" "NeptuneHub/AudioMuse-AI"; then + msg_info "Stopping Services" + systemctl stop audiomuse-ai audiomuse-ai-worker audiomuse-ai-worker-high audiomuse-ai-janitor audiomuse-ai-control + msg_ok "Stopped Services" + + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "audiomuse-ai" "NeptuneHub/AudioMuse-AI" "tarball" + + AUDIOMUSE_BACKEND="$(cat /opt/audiomuse-ai_data/.backend 2>/dev/null || echo cpu)" + REQ_COMMON="common.txt" + case "$AUDIOMUSE_BACKEND" in + gpu) + REQ_ACCEL="gpu.txt" + [[ "$(uname -m)" == "aarch64" ]] && REQ_ACCEL="gpu-arm64.txt" + ;; + cpu-noavx2) + REQ_COMMON="common-noavx2.txt" + REQ_ACCEL="cpu-noavx2.txt" + ;; + *) + REQ_ACCEL="cpu.txt" + ;; + esac + + msg_info "Updating Python Environment (${AUDIOMUSE_BACKEND})" + cd /opt/audiomuse-ai + $STD uv venv --seed --python 3.12 /opt/audiomuse-ai/.venv + $STD uv pip install --python /opt/audiomuse-ai/.venv \ + -r "/opt/audiomuse-ai/requirements/${REQ_COMMON}" \ + -r "/opt/audiomuse-ai/requirements/${REQ_ACCEL}" + msg_ok "Updated Python Environment (${AUDIOMUSE_BACKEND})" + + msg_info "Starting Services" + systemctl start audiomuse-ai audiomuse-ai-worker audiomuse-ai-worker-high audiomuse-ai-janitor audiomuse-ai-control + msg_ok "Started Services" + msg_ok "Updated successfully!" + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW}Access it using the following URL:${CL}" +echo -e "${GATEWAY}${BGN}http://${IP}:8000${CL}" diff --git a/ct/headers/audiomuse-ai b/ct/headers/audiomuse-ai new file mode 100644 index 000000000..168a3a149 --- /dev/null +++ b/ct/headers/audiomuse-ai @@ -0,0 +1,6 @@ + ___ ___ __ ___ ___ ____ + / | __ ______/ (_)___ / |/ /_ __________ / | / _/ + / /| |/ / / / __ / / __ \/ /|_/ / / / / ___/ _ \______/ /| | / / + / ___ / /_/ / /_/ / / /_/ / / / / /_/ (__ ) __/_____/ ___ |_/ / +/_/ |_\__,_/\__,_/_/\____/_/ /_/\__,_/____/\___/ /_/ |_/___/ + diff --git a/install/audiomuse-ai-install.sh b/install/audiomuse-ai-install.sh new file mode 100644 index 000000000..ad1240a21 --- /dev/null +++ b/install/audiomuse-ai-install.sh @@ -0,0 +1,250 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/NeptuneHub/AudioMuse-AI + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt install -y \ + build-essential \ + git \ + ffmpeg \ + libchromaprint-tools \ + libsndfile1 \ + libgomp1 +msg_ok "Installed Dependencies" + +PG_VERSION="16" setup_postgresql +PG_DB_NAME="audiomuse" PG_DB_USER="audiomuse" setup_postgresql_db +UV_PYTHON="3.12" setup_uv +setup_hwaccel + +fetch_and_deploy_gh_release "audiomuse-ai" "NeptuneHub/AudioMuse-AI" "tarball" + +var_backend="${var_backend:-auto}" +if [[ "$var_backend" == "auto" ]]; then + if ! grep -qm1 avx2 /proc/cpuinfo; then + var_backend="cpu-noavx2" + elif [[ "${HWACCEL_VENDOR:-none}" == "nvidia" ]]; then + var_backend="gpu" + else + var_backend="cpu" + fi +fi + +REQ_COMMON="common.txt" +case "$var_backend" in +gpu) + REQ_ACCEL="gpu.txt" + [[ "$(uname -m)" == "aarch64" ]] && REQ_ACCEL="gpu-arm64.txt" + ;; +cpu) + REQ_ACCEL="cpu.txt" + ;; +cpu-noavx2) + REQ_COMMON="common-noavx2.txt" + REQ_ACCEL="cpu-noavx2.txt" + ;; +*) + msg_error "Unknown var_backend '${var_backend}' (expected auto, gpu, cpu or cpu-noavx2)" + exit 1 + ;; +esac + +msg_info "Setting up Python Environment (${var_backend}, Patience)" +cd /opt/audiomuse-ai +$STD uv venv --seed --python 3.12 /opt/audiomuse-ai/.venv +$STD uv pip install --python /opt/audiomuse-ai/.venv \ + -r "/opt/audiomuse-ai/requirements/${REQ_COMMON}" \ + -r "/opt/audiomuse-ai/requirements/${REQ_ACCEL}" +mkdir -p /opt/audiomuse-ai_data +echo "$var_backend" >/opt/audiomuse-ai_data/.backend +msg_ok "Set up Python Environment (${var_backend})" + +MODEL_DIR="/opt/audiomuse-ai_data/model" +MODEL_URL="https://github.com/NeptuneHub/AudioMuse-AI/releases/download/v5.0.0-model" +DCLAP_URL="https://github.com/NeptuneHub/AudioMuse-AI-DCLAP/releases/download/v1" + +msg_info "Downloading ML Models (Patience)" +mkdir -p "$MODEL_DIR/huggingface" +for FILE in musicnn_embedding.onnx musicnn_prediction.onnx clap_text_model.onnx; do + curl -fsSL "${MODEL_URL}/${FILE}" -o "${MODEL_DIR}/${FILE}" +done +for FILE in model_epoch_36.onnx model_epoch_36.onnx.data; do + curl -fsSL "${DCLAP_URL}/${FILE}" -o "${MODEL_DIR}/${FILE}" +done +for BUNDLE in lyrics_model_whisper lyrics_model_silero_vad lyrics_model_gte_vnni; do + curl -fsSL "${MODEL_URL}/${BUNDLE}.tar.gz" -o "/tmp/${BUNDLE}.tar.gz" + tar -xzf "/tmp/${BUNDLE}.tar.gz" -C "$MODEL_DIR" + rm -f "/tmp/${BUNDLE}.tar.gz" +done +curl -fsSL "${MODEL_URL}/huggingface_models.tar.gz" -o /tmp/huggingface_models.tar.gz +tar -xzf /tmp/huggingface_models.tar.gz -C "${MODEL_DIR}/huggingface" +rm -f /tmp/huggingface_models.tar.gz +HF_HUB_DIR="${MODEL_DIR}/huggingface/hub" +rm -rf "${HF_HUB_DIR}/models--bert-base-uncased" "${HF_HUB_DIR}/models--facebook--bart-base" +if [[ -d "${HF_HUB_DIR}/models--roberta-base" ]]; then + find "${HF_HUB_DIR}/models--roberta-base/blobs" -type f -size +10M -delete + find "${HF_HUB_DIR}/models--roberta-base/snapshots" \( -name "model.safetensors" -o -name "pytorch_model.bin" \) -delete +fi +msg_ok "Downloaded ML Models" + +msg_info "Configuring AudioMuse-AI" +mkdir -p /opt/audiomuse-ai_data/{temp_audio,ivf_cache,plugins,backup} /opt/audiomuse-ai_data/cache/numba +AUDIOMUSE_PASSWORD=$(openssl rand -base64 18) +JWT_SECRET=$(openssl rand -hex 32) +API_TOKEN=$(openssl rand -hex 32) +cat </opt/audiomuse-ai_data/audiomuse.env +POSTGRES_USER=audiomuse +POSTGRES_PASSWORD=${PG_DB_PASS} +POSTGRES_DB=audiomuse +POSTGRES_HOST=127.0.0.1 +POSTGRES_PORT=5432 +TZ=UTC +AUTH_ENABLED=true +AUDIOMUSE_USER=admin +AUDIOMUSE_PASSWORD=${AUDIOMUSE_PASSWORD} +JWT_SECRET=${JWT_SECRET} +API_TOKEN=${API_TOKEN} +MEDIASERVER_TYPE=jellyfin +JELLYFIN_URL=http://YOUR_JELLYFIN_IP:8096 +JELLYFIN_USER_ID= +JELLYFIN_TOKEN= +AI_MODEL_PROVIDER=NONE +APP_DATA_DIR=/opt/audiomuse-ai_data +TEMP_DIR=/opt/audiomuse-ai_data/temp_audio +BACKUP_DIR=/opt/audiomuse-ai_data/backup +RESTORE_LOG_DIR=/opt/audiomuse-ai_data/backup +XDG_CACHE_HOME=/opt/audiomuse-ai_data/cache +NUMBA_CACHE_DIR=/opt/audiomuse-ai_data/cache/numba +HF_HOME=${MODEL_DIR}/huggingface +HF_HUB_DISABLE_XET=1 +HF_XET_DISABLE=1 +EMBEDDING_MODEL_PATH=${MODEL_DIR}/musicnn_embedding.onnx +PREDICTION_MODEL_PATH=${MODEL_DIR}/musicnn_prediction.onnx +CLAP_AUDIO_MODEL_PATH=${MODEL_DIR}/model_epoch_36.onnx +CLAP_TEXT_MODEL_PATH=${MODEL_DIR}/clap_text_model.onnx +LYRICS_MODEL_DIR=${MODEL_DIR} +LYRICS_WHISPER_MODEL_DIR=${MODEL_DIR}/whisper-small-onnx +SILERO_VAD_ONNX_PATH=${MODEL_DIR}/silero_vad.onnx +LYRICS_GTE_ONNX_PATH=${MODEL_DIR}/gte-multilingual-base-int8.onnx +LYRICS_GTE_TOKENIZER_DIR=${MODEL_DIR}/gte-multilingual-base +EOF +{ + echo "" + echo "AudioMuse-AI-Credentials" + echo "Web UI User: admin" + echo "Web UI Password: ${AUDIOMUSE_PASSWORD}" +} >>~/audiomuse-ai.creds +msg_ok "Configured AudioMuse-AI" + +msg_info "Creating Services" +cat </etc/systemd/system/audiomuse-ai.service +[Unit] +Description=AudioMuse-AI Web (Flask) +After=network-online.target postgresql.service +Wants=network-online.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/audiomuse-ai +EnvironmentFile=/opt/audiomuse-ai_data/audiomuse.env +ExecStart=/opt/audiomuse-ai/.venv/bin/gunicorn --bind 0.0.0.0:8000 --workers 1 --threads 4 --worker-class gthread --keep-alive 5 --timeout 300 app:app +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/audiomuse-ai-worker.service +[Unit] +Description=AudioMuse-AI Queue Worker (default) +After=network-online.target postgresql.service audiomuse-ai.service +Wants=network-online.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/audiomuse-ai +EnvironmentFile=/opt/audiomuse-ai_data/audiomuse.env +ExecStart=/opt/audiomuse-ai/.venv/bin/python -u -m taskqueue.worker --queue default +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/audiomuse-ai-worker-high.service +[Unit] +Description=AudioMuse-AI Queue Worker (high) +After=network-online.target postgresql.service audiomuse-ai.service +Wants=network-online.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/audiomuse-ai +EnvironmentFile=/opt/audiomuse-ai_data/audiomuse.env +ExecStart=/opt/audiomuse-ai/.venv/bin/python -u -m taskqueue.worker --queue high +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/audiomuse-ai-janitor.service +[Unit] +Description=AudioMuse-AI Queue Maintenance +After=network-online.target postgresql.service audiomuse-ai.service +Wants=network-online.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/audiomuse-ai +EnvironmentFile=/opt/audiomuse-ai_data/audiomuse.env +ExecStart=/opt/audiomuse-ai/.venv/bin/python -u -m taskqueue.maintenance +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/audiomuse-ai-control.service +[Unit] +Description=AudioMuse-AI Config Restart Listener +After=network-online.target postgresql.service audiomuse-ai.service +Wants=network-online.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/audiomuse-ai +EnvironmentFile=/opt/audiomuse-ai_data/audiomuse.env +ExecStart=/opt/audiomuse-ai/.venv/bin/python -u -m taskqueue.control +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now audiomuse-ai audiomuse-ai-worker audiomuse-ai-worker-high audiomuse-ai-janitor audiomuse-ai-control +msg_ok "Created Services" + +motd_ssh +customize +cleanup_lxc