Skip to content

Build Executables

Build Executables #18

name: Build Executables
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: '要上传资源的 Release 标签(如 v1.2.0),留空则上传到最新 Release'
required: false
default: ''
permissions:
contents: write
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
variant: CPU
platform: Windows
pytorch_url: https://download.pytorch.org/whl/cpu
sep: ";"
shell: pwsh
- os: windows-latest
variant: GPU
platform: Windows
pytorch_url: https://download.pytorch.org/whl/cu121
sep: ";"
shell: pwsh
- os: ubuntu-latest
variant: CPU
platform: Linux
pytorch_url: https://download.pytorch.org/whl/cpu
sep: ":"
shell: bash
- os: ubuntu-latest
variant: GPU
platform: Linux
pytorch_url: https://download.pytorch.org/whl/cu121
sep: ":"
shell: bash
runs-on: ${{ matrix.os }}
name: Build ${{ matrix.platform }}-${{ matrix.variant }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y build-essential libsndfile1 ffmpeg portaudio19-dev
- name: Install Python dependencies
run: |
python -m pip install --upgrade "pip<24.1"
pip install pyinstaller
pip install torch torchaudio --index-url ${{ matrix.pytorch_url }}
pip install omegaconf==2.0.6 --no-deps
pip install PyYAML antlr4-python3-runtime hydra-core
pip install fairseq==0.12.2 --no-deps
pip install gradio==3.50.2 librosa soundfile scipy numpy praat-parselmouth pyworld torchcrepe faiss-cpu tqdm requests python-dotenv colorama demucs huggingface_hub pedalboard ffmpeg-python av
- name: Download base models
run: python tools/download_models.py
env:
PYTHONIOENCODING: utf-8
- name: Build executable
shell: bash
run: |
SEP="${{ matrix.sep }}"
NAME="AI-RVC-${{ matrix.platform }}-${{ matrix.variant }}"
pyinstaller --name "${NAME}" \
--onedir \
--add-data "ui${SEP}ui" \
--add-data "infer${SEP}infer" \
--add-data "lib${SEP}lib" \
--add-data "models${SEP}models" \
--add-data "tools${SEP}tools" \
--add-data "i18n${SEP}i18n" \
--add-data "configs${SEP}configs" \
--add-data "assets/hubert${SEP}assets/hubert" \
--add-data "assets/rmvpe${SEP}assets/rmvpe" \
--hidden-import=torch \
--hidden-import=torchaudio \
--hidden-import=gradio \
--hidden-import=librosa \
--hidden-import=soundfile \
--hidden-import=fairseq \
--hidden-import=audio_separator \
--hidden-import=demucs \
--hidden-import=pedalboard \
--collect-all torch \
--collect-all torchaudio \
--collect-all gradio \
run.py
- name: Create portable package
shell: bash
run: |
NAME="AI-RVC-${{ matrix.platform }}-${{ matrix.variant }}"
PKG="${NAME}-Portable"
mkdir -p "${PKG}"
# onedir 输出在 dist/NAME/ 目录下,复制全部内容
cp -r dist/${NAME}/* "${PKG}/"
cp README.md "${PKG}/"
[ -f LICENSE ] && cp LICENSE "${PKG}/"
if [ "${{ matrix.variant }}" = "GPU" ]; then
VARIANT_NOTE="GPU 版(CUDA 12.1),支持 NVIDIA 显卡加速
如果没有 NVIDIA 显卡,程序会自动回退到 CPU 推理"
else
VARIANT_NOTE="CPU 版,无需显卡即可运行
如需 GPU 加速,请下载 GPU 版本或使用本地安装方式:python install.py"
fi
if [ "${{ matrix.platform }}" = "Windows" ]; then
EXE_NAME="${NAME}.exe"
cat > "${PKG}/使用说明.txt" << HEREDOC
AI-RVC ${{ matrix.platform }} 便携版(${{ matrix.variant }})
使用方法:
双击 ${EXE_NAME} 启动
浏览器访问 http://127.0.0.1:7860
${VARIANT_NOTE}
首次启动会自动下载所需模型(约 5-10 分钟)
无需安装 Python,解压即用
HEREDOC
else
EXE_NAME="${NAME}"
chmod +x "${PKG}/${EXE_NAME}"
cat > "${PKG}/使用说明.txt" << HEREDOC
AI-RVC ${{ matrix.platform }} 便携版(${{ matrix.variant }})
使用方法:
chmod +x ${EXE_NAME}
./${EXE_NAME}
浏览器访问 http://127.0.0.1:7860
${VARIANT_NOTE}
首次启动会自动下载所需模型(约 5-10 分钟)
无需安装 Python,解压即用
HEREDOC
fi
- name: Compress package
shell: bash
run: |
NAME="AI-RVC-${{ matrix.platform }}-${{ matrix.variant }}"
PKG="${NAME}-Portable"
if [ "${{ matrix.platform }}" = "Windows" ]; then
# 先压缩成 zip
7z a -tzip "${PKG}.zip" "${PKG}"
# 超过 1.9GB 时删除 zip 改用 7z(压缩率更高)
FILE_SIZE=$(stat -c%s "${PKG}.zip" 2>/dev/null || wc -c < "${PKG}.zip" | tr -d ' ')
if [ "$FILE_SIZE" -gt 1900000000 ]; then
rm "${PKG}.zip"
# 先尝试不分卷的 7z
7z a "${PKG}.7z" "${PKG}"
SEVENZ_SIZE=$(stat -c%s "${PKG}.7z" 2>/dev/null || wc -c < "${PKG}.7z" | tr -d ' ')
if [ "$SEVENZ_SIZE" -gt 1900000000 ]; then
# 7z 也超限,改用分卷
rm "${PKG}.7z"
7z a -v1900m "${PKG}.7z" "${PKG}"
fi
fi
else
tar -czf "${PKG}.tar.gz" "${PKG}"
# 超过 1.9GB 时拆分
FILE_SIZE=$(stat -c%s "${PKG}.tar.gz" 2>/dev/null || stat -f%z "${PKG}.tar.gz")
if [ "$FILE_SIZE" -gt 1900000000 ]; then
split -b 1900M "${PKG}.tar.gz" "${PKG}.tar.gz.part"
rm "${PKG}.tar.gz"
fi
fi
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: AI-RVC-${{ matrix.platform }}-${{ matrix.variant }}
path: AI-RVC-${{ matrix.platform }}-${{ matrix.variant }}-Portable*
upload-release:
needs: [build]
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
merge-multiple: true
- name: List artifacts
run: ls -lh AI-RVC-*
- name: Determine target tag
id: tag
run: |
if [ "${{ github.event_name }}" = "push" ]; then
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
elif [ -n "${{ github.event.inputs.tag }}" ]; then
echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
else
LATEST=$(gh release list --repo ${{ github.repository }} --limit 1 --json tagName -q '.[0].tagName')
echo "tag=${LATEST}" >> $GITHUB_OUTPUT
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload assets to release
run: |
TAG="${{ steps.tag.outputs.tag }}"
echo "上传资源到 Release: ${TAG}"
# 收集所有构建产物(含分卷文件)
FILES=$(find . -maxdepth 1 -name "AI-RVC-*-Portable*" -type f | sort)
echo "找到以下文件:"
echo "$FILES" | while read f; do
SIZE=$(stat -c%s "$f" 2>/dev/null || stat -f%z "$f")
echo " $f ($(( SIZE / 1048576 )) MB)"
done
# 逐个上传
echo "$FILES" | while read f; do
echo "上传: $f"
gh release upload "${TAG}" "$f" \
--repo ${{ github.repository }} \
--clobber
done
echo "全部上传完成"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}