Compare commits
3
Commits
0584397884
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f441defcc | ||
|
|
e9ea6b9bab | ||
|
|
c7953dc4e0 |
@@ -200,5 +200,4 @@ ui/components_demo.py
|
||||
data_sampler_demo.py
|
||||
pipeline_ace_step_demo.py
|
||||
*.wav
|
||||
start.sh
|
||||
exps/*
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
- [✨ Features](#-features)
|
||||
- [📦 Installation](#-installation)
|
||||
- [⚡ Quick Start (Windows)](#-quick-start-windows)
|
||||
- [⚡ Quick Start](#-quick-start)
|
||||
- [🚀 Usage](#-usage)
|
||||
- [📱 User Interface Guide](#-user-interface-guide)
|
||||
- [🔨 Train](#-train)
|
||||
@@ -260,19 +260,30 @@ pip3 install torch torchvision torchaudio --index-url https://download.pytorch.o
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
If you also intend to train or fine-tune, install the training extras as well (they are not needed for inference):
|
||||
```bash
|
||||
pip install -e ".[train]"
|
||||
```
|
||||
|
||||
The ACE-Step application is now installed. The GUI works on Windows, macOS, and Linux. For instructions on how to run it, please see the [Usage](#-usage) section.
|
||||
|
||||
|
||||
## ⚡ Quick Start (Windows)
|
||||
## ⚡ Quick Start
|
||||
|
||||
This repository ships with [`start.bat`](./start.bat), which does everything for you: checks Python, creates the virtual environment, installs PyTorch with CUDA support, installs ACE-Step, and launches the web UI.
|
||||
This repository ships with launcher scripts that do everything for you: check Python, create the virtual environment, install PyTorch with the right backend, install ACE-Step, and launch the web UI.
|
||||
|
||||
Just double-click `start.bat`, or run it from a command prompt:
|
||||
**Windows** — double-click [`start.bat`](./start.bat), or run it from a command prompt:
|
||||
|
||||
```bat
|
||||
start.bat
|
||||
```
|
||||
|
||||
**Linux / macOS** — run [`start.sh`](./start.sh):
|
||||
|
||||
```bash
|
||||
./start.sh
|
||||
```
|
||||
|
||||
The first run takes a few minutes (roughly 3 GB of packages are downloaded). Model weights (~8 GB) are fetched automatically on the first generation. Later runs start immediately.
|
||||
|
||||
### Script flags
|
||||
@@ -296,7 +307,7 @@ Flags can be combined, for example:
|
||||
start.bat --lowvram --listen --port 7870
|
||||
```
|
||||
|
||||
Defaults (port, GPU index, checkpoint path) live in the settings block at the top of `start.bat`.
|
||||
Defaults (port, GPU index, checkpoint path) live in the settings block at the top of each script. In `start.sh` they can also be overridden with environment variables (`PORT=7870 ./start.sh`). On macOS the scripts install the MPS build of PyTorch and pass `--bf16 false` automatically.
|
||||
|
||||
|
||||
## 🚀 Usage
|
||||
@@ -321,6 +332,22 @@ acestep --checkpoint_path /path/to/checkpoint --port 7865 --device_id 0 --share
|
||||
|
||||
If you are using macOS, please use `--bf16 false` to avoid errors.
|
||||
|
||||
#### 🖥️ Command Line Generation
|
||||
|
||||
To generate without the web UI, use `infer.py`:
|
||||
|
||||
```bash
|
||||
python infer.py \
|
||||
--prompt "synth-pop, female vocal, warm analog synths, 110 bpm" \
|
||||
--lyrics_file my_song.txt \
|
||||
--duration 120 --steps 60 --seed 7 \
|
||||
--format mp3 --output_path outputs/my_song.mp3
|
||||
```
|
||||
|
||||
Run `python infer.py --help` for the full list. The main options are `--prompt`, `--lyrics` / `--lyrics_file`, `--duration`, `--steps`, `--guidance_scale`, `--scheduler`, `--cfg_type`, `--omega_scale`, `--seed`, `--format` and `--output_path`; the runtime flags (`--bf16`, `--cpu_offload`, `--overlapped_decode`, `--torch_compile`, `--device_id`) match the ones the GUI takes.
|
||||
|
||||
With no `--prompt`, the script keeps its original behaviour and generates from a random example in `examples/input_params`.
|
||||
|
||||
#### 🔍 API Usage
|
||||
If you intend to integrate ACE-Step as a library into your own Python projects, you can install the latest version directly from GitHub using the following pip command.
|
||||
|
||||
|
||||
+33
-5
@@ -22,7 +22,7 @@
|
||||
|
||||
- [✨ Возможности](#-возможности)
|
||||
- [📦 Установка](#-установка)
|
||||
- [⚡ Быстрый старт на Windows](#-быстрый-старт-на-windows)
|
||||
- [⚡ Быстрый старт](#-быстрый-старт)
|
||||
- [🚀 Использование](#-использование)
|
||||
- [📱 Описание интерфейса](#-описание-интерфейса)
|
||||
- [🔨 Обучение](#-обучение)
|
||||
@@ -261,19 +261,30 @@ pip3 install torch torchvision torchaudio --index-url https://download.pytorch.o
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
Если планируете обучать или дообучать модель, поставьте дополнительно зависимости для обучения — для инференса они не нужны:
|
||||
```bash
|
||||
pip install -e ".[train]"
|
||||
```
|
||||
|
||||
На этом установка завершена. Графический интерфейс работает на Windows, macOS и Linux. Как запускать — см. раздел [Использование](#-использование).
|
||||
|
||||
|
||||
## ⚡ Быстрый старт на Windows
|
||||
## ⚡ Быстрый старт
|
||||
|
||||
В репозитории есть скрипт [`start.bat`](./start.bat), который делает всё сам: проверяет Python, создаёт виртуальное окружение, ставит PyTorch с поддержкой CUDA, устанавливает ACE-Step и запускает веб-интерфейс.
|
||||
В репозитории есть скрипты запуска, которые делают всё сами: проверяют Python, создают виртуальное окружение, ставят PyTorch с нужным бэкендом, устанавливают ACE-Step и запускают веб-интерфейс.
|
||||
|
||||
Достаточно дважды кликнуть по `start.bat` — или запустить из командной строки:
|
||||
**Windows** — достаточно дважды кликнуть по [`start.bat`](./start.bat) или запустить из командной строки:
|
||||
|
||||
```bat
|
||||
start.bat
|
||||
```
|
||||
|
||||
**Linux / macOS** — запустите [`start.sh`](./start.sh):
|
||||
|
||||
```bash
|
||||
./start.sh
|
||||
```
|
||||
|
||||
При первом запуске установка займёт несколько минут (скачивается около 3 ГБ пакетов). Веса модели (~8 ГБ) докачаются автоматически при первой генерации. Последующие запуски стартуют сразу.
|
||||
|
||||
### Флаги скрипта
|
||||
@@ -284,6 +295,7 @@ start.bat
|
||||
| `--cpu` | Запуск на процессоре, без CUDA (очень медленно, но работает без видеокарты NVIDIA) |
|
||||
| `--share` | Публичная ссылка Gradio для доступа снаружи |
|
||||
| `--port <N>` | Порт веб-интерфейса (по умолчанию 7865) |
|
||||
| `--device <N>` | Номер видеокарты (по умолчанию 0) |
|
||||
| `--listen` | Слушать `0.0.0.0`, чтобы зайти с других устройств в локальной сети |
|
||||
| `--reinstall` | Полностью пересоздать виртуальное окружение с нуля |
|
||||
| `--update` | Обновить зависимости в существующем окружении |
|
||||
@@ -296,7 +308,7 @@ start.bat
|
||||
start.bat --lowvram --listen --port 7870
|
||||
```
|
||||
|
||||
Настройки по умолчанию (порт, номер GPU, путь к весам модели) задаются в блоке `==== НАСТРОЙКИ ====` в начале файла `start.bat`.
|
||||
Настройки по умолчанию (порт, номер GPU, путь к весам модели) задаются в блоке `==== НАСТРОЙКИ ====` в начале каждого скрипта. В `start.sh` их можно переопределить переменными окружения (`PORT=7870 ./start.sh`). На macOS скрипт сам ставит сборку PyTorch с MPS и передаёт `--bf16 false`.
|
||||
|
||||
|
||||
## 🚀 Использование
|
||||
@@ -321,6 +333,22 @@ acestep --checkpoint_path /path/to/checkpoint --port 7865 --device_id 0 --share
|
||||
|
||||
На macOS используйте `--bf16 false`, чтобы избежать ошибок.
|
||||
|
||||
#### 🖥️ Генерация из командной строки
|
||||
|
||||
Чтобы генерировать без веб-интерфейса, используйте `infer.py`:
|
||||
|
||||
```bash
|
||||
python infer.py \
|
||||
--prompt "synth-pop, female vocal, warm analog synths, 110 bpm" \
|
||||
--lyrics_file my_song.txt \
|
||||
--duration 120 --steps 60 --seed 7 \
|
||||
--format mp3 --output_path outputs/my_song.mp3
|
||||
```
|
||||
|
||||
Полный список — `python infer.py --help`. Основные опции: `--prompt`, `--lyrics` / `--lyrics_file`, `--duration`, `--steps`, `--guidance_scale`, `--scheduler`, `--cfg_type`, `--omega_scale`, `--seed`, `--format`, `--output_path`. Флаги режима работы (`--bf16`, `--cpu_offload`, `--overlapped_decode`, `--torch_compile`, `--device_id`) те же, что у графического интерфейса.
|
||||
|
||||
Без `--prompt` скрипт ведёт себя как раньше и генерирует по случайному примеру из `examples/input_params`.
|
||||
|
||||
#### 🔍 Использование как библиотеки
|
||||
Если вы хотите встроить ACE-Step как библиотеку в собственный Python-проект, можно поставить последнюю версию прямо из GitHub.
|
||||
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# Training Instruction
|
||||
|
||||
## 0. Install the Training Dependencies
|
||||
|
||||
Training needs a few packages that a plain inference install does not pull in
|
||||
(`datasets`, `pytorch_lightning`, `matplotlib`, `tensorboard`, `tensorboardX`).
|
||||
Install them with the `train` extra:
|
||||
|
||||
```bash
|
||||
pip install -e ".[train]"
|
||||
```
|
||||
|
||||
## 1. Data Preparation
|
||||
|
||||
### Required File Format
|
||||
|
||||
@@ -101,7 +101,17 @@ def create_text2music_ui(
|
||||
if not os.path.isdir(output_file_dir):
|
||||
os.makedirs(output_file_dir, exist_ok=True)
|
||||
json_files = [f for f in os.listdir(output_file_dir) if f.endswith('.json')]
|
||||
json_files.sort(reverse=True, key=lambda x: int(x.split('_')[1]))
|
||||
|
||||
def _mtime(name):
|
||||
# Output filenames are user-controlled (infer.py --output_path, or the
|
||||
# save_path passed from the UI), so a timestamp cannot be parsed out of
|
||||
# them: doing so used to raise ValueError and take the whole UI down.
|
||||
try:
|
||||
return os.path.getmtime(os.path.join(output_file_dir, name))
|
||||
except OSError:
|
||||
return 0.0
|
||||
|
||||
json_files.sort(key=_mtime, reverse=True)
|
||||
output_files = gr.Dropdown(choices=json_files, label="Select previous generated input params", scale=9, interactive=True)
|
||||
load_bnt = gr.Button("Load", variant="primary", scale=1)
|
||||
|
||||
|
||||
@@ -48,7 +48,66 @@ def sample_data(json_data):
|
||||
)
|
||||
@click.option("--device_id", type=int, default=0, help="Device ID to use")
|
||||
@click.option("--output_path", type=str, default=None, help="Path to save the output")
|
||||
def main(checkpoint_path, bf16, torch_compile, cpu_offload, overlapped_decode, device_id, output_path):
|
||||
# --- generation parameters -------------------------------------------------
|
||||
# Without --prompt the script keeps its original behaviour and generates from a
|
||||
# random example in examples/input_params.
|
||||
@click.option(
|
||||
"--prompt",
|
||||
type=str,
|
||||
default=None,
|
||||
help="Style tags or description, comma separated. If omitted, a random example is used.",
|
||||
)
|
||||
@click.option("--lyrics", type=str, default=None, help="Lyrics, with [verse]/[chorus] tags.")
|
||||
@click.option(
|
||||
"--lyrics_file",
|
||||
type=click.Path(exists=True, dir_okay=False),
|
||||
default=None,
|
||||
help="Read lyrics from a UTF-8 file. Takes precedence over --lyrics.",
|
||||
)
|
||||
@click.option("--duration", type=float, default=60.0, help="Audio duration in seconds (-1 for random).")
|
||||
@click.option("--steps", type=int, default=60, help="Number of inference steps.")
|
||||
@click.option("--guidance_scale", type=float, default=15.0, help="Guidance scale.")
|
||||
@click.option(
|
||||
"--scheduler",
|
||||
type=click.Choice(["euler", "heun", "pingpong"]),
|
||||
default="euler",
|
||||
help="Scheduler type.",
|
||||
)
|
||||
@click.option(
|
||||
"--cfg_type",
|
||||
type=click.Choice(["cfg", "apg", "cfg_star"]),
|
||||
default="apg",
|
||||
help="CFG type. apg is recommended.",
|
||||
)
|
||||
@click.option("--omega_scale", type=float, default=10.0, help="Granularity scale.")
|
||||
@click.option("--seed", type=str, default=None, help="Manual seeds, comma separated. Random if omitted.")
|
||||
@click.option(
|
||||
"--format",
|
||||
"audio_format",
|
||||
type=click.Choice(["wav", "mp3", "ogg", "flac"]),
|
||||
default="wav",
|
||||
help="Output audio format.",
|
||||
)
|
||||
def main(
|
||||
checkpoint_path,
|
||||
bf16,
|
||||
torch_compile,
|
||||
cpu_offload,
|
||||
overlapped_decode,
|
||||
device_id,
|
||||
output_path,
|
||||
prompt,
|
||||
lyrics,
|
||||
lyrics_file,
|
||||
duration,
|
||||
steps,
|
||||
guidance_scale,
|
||||
scheduler,
|
||||
cfg_type,
|
||||
omega_scale,
|
||||
seed,
|
||||
audio_format,
|
||||
):
|
||||
os.environ["CUDA_VISIBLE_DEVICES"] = str(device_id)
|
||||
|
||||
model_demo = ACEStepPipeline(
|
||||
@@ -58,23 +117,24 @@ def main(checkpoint_path, bf16, torch_compile, cpu_offload, overlapped_decode, d
|
||||
cpu_offload=cpu_offload,
|
||||
overlapped_decode=overlapped_decode
|
||||
)
|
||||
print(model_demo)
|
||||
|
||||
if lyrics_file is not None:
|
||||
with open(lyrics_file, "r", encoding="utf-8") as f:
|
||||
lyrics = f.read()
|
||||
|
||||
if prompt is None:
|
||||
# No prompt given: keep the original behaviour and use a random example.
|
||||
data_sampler = DataSampler()
|
||||
|
||||
json_data = data_sampler.sample()
|
||||
json_data = sample_data(json_data)
|
||||
print(json_data)
|
||||
|
||||
(
|
||||
audio_duration,
|
||||
prompt,
|
||||
lyrics,
|
||||
sampled_lyrics,
|
||||
infer_step,
|
||||
guidance_scale,
|
||||
sampled_guidance_scale,
|
||||
scheduler_type,
|
||||
cfg_type,
|
||||
omega_scale,
|
||||
sampled_cfg_type,
|
||||
sampled_omega_scale,
|
||||
manual_seeds,
|
||||
guidance_interval,
|
||||
guidance_interval_decay,
|
||||
@@ -85,17 +145,42 @@ def main(checkpoint_path, bf16, torch_compile, cpu_offload, overlapped_decode, d
|
||||
oss_steps,
|
||||
guidance_scale_text,
|
||||
guidance_scale_lyric,
|
||||
) = json_data
|
||||
) = sample_data(json_data)
|
||||
# Explicit options still win over the sampled example.
|
||||
lyrics = lyrics if lyrics is not None else sampled_lyrics
|
||||
manual_seeds = seed if seed is not None else manual_seeds
|
||||
else:
|
||||
audio_duration = duration
|
||||
lyrics = lyrics if lyrics is not None else "[instrumental]"
|
||||
infer_step = steps
|
||||
sampled_guidance_scale = guidance_scale
|
||||
scheduler_type = scheduler
|
||||
sampled_cfg_type = cfg_type
|
||||
sampled_omega_scale = omega_scale
|
||||
manual_seeds = seed
|
||||
guidance_interval = 0.5
|
||||
guidance_interval_decay = 0.0
|
||||
min_guidance_scale = 3.0
|
||||
use_erg_tag = True
|
||||
use_erg_lyric = True
|
||||
use_erg_diffusion = True
|
||||
oss_steps = None
|
||||
guidance_scale_text = 0.0
|
||||
guidance_scale_lyric = 0.0
|
||||
|
||||
click.echo(f"prompt: {prompt}")
|
||||
click.echo(f"duration: {audio_duration}s, steps: {infer_step}, seeds: {manual_seeds}")
|
||||
|
||||
model_demo(
|
||||
format=audio_format,
|
||||
audio_duration=audio_duration,
|
||||
prompt=prompt,
|
||||
lyrics=lyrics,
|
||||
infer_step=infer_step,
|
||||
guidance_scale=guidance_scale,
|
||||
guidance_scale=sampled_guidance_scale,
|
||||
scheduler_type=scheduler_type,
|
||||
cfg_type=cfg_type,
|
||||
omega_scale=omega_scale,
|
||||
cfg_type=sampled_cfg_type,
|
||||
omega_scale=sampled_omega_scale,
|
||||
manual_seeds=manual_seeds,
|
||||
guidance_interval=guidance_interval,
|
||||
guidance_interval_decay=guidance_interval_decay,
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# Training-only dependencies (trainer.py, convert2hf_dataset.py).
|
||||
# Install with: pip install -e ".[train]"
|
||||
datasets==3.4.1
|
||||
pytorch_lightning==2.5.1
|
||||
matplotlib==3.10.1
|
||||
tensorboard
|
||||
tensorboardX
|
||||
@@ -1,12 +1,9 @@
|
||||
datasets==3.4.1
|
||||
diffusers>=0.33.0
|
||||
gradio>=6.0.0
|
||||
librosa==0.11.0
|
||||
loguru==0.7.3
|
||||
matplotlib==3.10.1
|
||||
numpy
|
||||
pypinyin==0.53.0
|
||||
pytorch_lightning==2.5.1
|
||||
soundfile==0.13.1
|
||||
torch
|
||||
torchaudio
|
||||
@@ -22,5 +19,3 @@ cutlet
|
||||
fugashi[unidic-lite]
|
||||
click
|
||||
peft
|
||||
tensorboard
|
||||
tensorboardX
|
||||
@@ -1,5 +1,16 @@
|
||||
from setuptools import setup, find_namespace_packages
|
||||
|
||||
|
||||
def read_requirements(path):
|
||||
"""Read a requirements file, skipping comments and blank lines."""
|
||||
with open(path, encoding="utf-8") as f:
|
||||
return [
|
||||
line.strip()
|
||||
for line in f
|
||||
if line.strip() and not line.lstrip().startswith("#")
|
||||
]
|
||||
|
||||
|
||||
setup(
|
||||
name="ace_step",
|
||||
description="ACE Step: A Step Towards Music Generation Foundation Model",
|
||||
@@ -7,7 +18,7 @@ setup(
|
||||
long_description_content_type="text/markdown",
|
||||
version="0.2.0",
|
||||
packages=find_namespace_packages(),
|
||||
install_requires=open("requirements.txt", encoding="utf-8").read().splitlines(),
|
||||
install_requires=read_requirements("requirements.txt"),
|
||||
author="ACE Studio, StepFun AI",
|
||||
license="Apache 2.0",
|
||||
classifiers=[
|
||||
@@ -25,10 +36,7 @@ setup(
|
||||
"acestep.models.lyrics_utils": ["vocab.json"], # Specify the relative path to vocab.json
|
||||
},
|
||||
extras_require={
|
||||
"train": [
|
||||
"peft",
|
||||
"tensorboard",
|
||||
"tensorboardX"
|
||||
]
|
||||
# Only needed to train or fine-tune; inference does not import these.
|
||||
"train": read_requirements("requirements-train.txt"),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -68,8 +68,15 @@ if "%DO_REINSTALL%"=="1" (
|
||||
)
|
||||
|
||||
REM ------------------------- поиск Python -------------------------
|
||||
if exist "%VENV_PY%" goto venv_ready
|
||||
REM Рабочим считаем окружение, в котором есть и python, и pip: каталог от
|
||||
REM прерванной установки выглядит как готовый, но валится дальше с невнятной
|
||||
REM ошибкой про интернет.
|
||||
if not exist "%VENV_PY%" goto venv_create
|
||||
"%VENV_PY%" -m pip --version >nul 2>&1 && goto venv_ready
|
||||
echo [1/4] Окружение "%VENV_DIR%" неработоспособно, пересоздаю...
|
||||
rmdir /s /q "%VENV_DIR%"
|
||||
|
||||
:venv_create
|
||||
echo [1/4] Ищу подходящий Python...
|
||||
set "SYS_PY="
|
||||
for %%V in (3.12 3.11 3.10 3.13) do (
|
||||
@@ -92,14 +99,9 @@ echo Найден Python %PYVER% (%SYS_PY%)
|
||||
|
||||
echo [1/4] Создаю виртуальное окружение в "%VENV_DIR%"...
|
||||
%SYS_PY% -m venv "%VENV_DIR%"
|
||||
if errorlevel 1 (
|
||||
echo [ОШИБКА] Не удалось создать виртуальное окружение.
|
||||
goto fail
|
||||
)
|
||||
if not exist "%VENV_PY%" (
|
||||
echo [ОШИБКА] Виртуальное окружение создано некорректно: нет "%VENV_PY%".
|
||||
goto fail
|
||||
)
|
||||
if errorlevel 1 goto venv_failed
|
||||
if not exist "%VENV_PY%" goto venv_failed
|
||||
"%VENV_PY%" -m pip --version >nul 2>&1 || goto venv_failed
|
||||
set "FRESH_VENV=1"
|
||||
|
||||
:venv_ready
|
||||
@@ -205,9 +207,12 @@ if "%OPT_LOWVRAM%"=="1" set "ARGS=%ARGS% --cpu_offload true --overlapped_decode
|
||||
|
||||
echo [4/4] Запускаю веб-интерфейс...
|
||||
echo.
|
||||
echo Адрес: http://%SERVER_NAME%:%PORT%
|
||||
if "%OPT_LOWVRAM%"=="1" echo Режим: экономия видеопамяти
|
||||
echo Первый запуск скачивает веса модели (~8 ГБ) - наберитесь терпения.
|
||||
echo Идёт загрузка моделей, это занимает время.
|
||||
echo При первом запуске дополнительно скачиваются веса (~8 ГБ).
|
||||
echo.
|
||||
echo Интерфейс будет доступен на http://%SERVER_NAME%:%PORT%
|
||||
echo когда ниже появится строка "Running on local URL".
|
||||
echo Остановить: Ctrl+C в этом окне.
|
||||
echo.
|
||||
|
||||
@@ -240,6 +245,13 @@ echo.
|
||||
goto success
|
||||
|
||||
REM ------------------------- завершение -------------------------
|
||||
:venv_failed
|
||||
echo.
|
||||
echo [ОШИБКА] Не удалось создать рабочее виртуальное окружение в "%VENV_DIR%".
|
||||
echo Переустановите Python с https://www.python.org/downloads/,
|
||||
echo отметив "Add Python to PATH", и запустите "%SCRIPT_NAME% --reinstall".
|
||||
goto fail
|
||||
|
||||
:fail
|
||||
echo.
|
||||
pause
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
#!/usr/bin/env bash
|
||||
# ACE-Step: настройка окружения и запуск веб-интерфейса на Linux / macOS.
|
||||
# Windows-аналог — start.bat.
|
||||
set -uo pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# ============================ НАСТРОЙКИ ============================
|
||||
VENV_DIR="${VENV_DIR:-venv}" # каталог виртуального окружения
|
||||
PORT="${PORT:-7865}" # порт веб-интерфейса
|
||||
SERVER_NAME="${SERVER_NAME:-127.0.0.1}" # 0.0.0.0 — доступ из локальной сети
|
||||
DEVICE_ID="${DEVICE_ID:-0}" # номер видеокарты
|
||||
CHECKPOINT_PATH="${CHECKPOINT_PATH:-}" # пусто — скачать в ~/.cache/ace-step
|
||||
# Сборка PyTorch под CUDA (cu126 / cu124 / cu121). Только для Linux.
|
||||
TORCH_INDEX="${TORCH_INDEX:-https://download.pytorch.org/whl/cu126}"
|
||||
# ==================================================================
|
||||
|
||||
SCRIPT_NAME="$(basename "$0")"
|
||||
OPT_LOWVRAM=0
|
||||
OPT_CPU=0
|
||||
OPT_SHARE=0
|
||||
DO_SETUP_ONLY=0
|
||||
DO_REINSTALL=0
|
||||
DO_UPDATE=0
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
|
||||
Использование: ./$SCRIPT_NAME [флаги]
|
||||
|
||||
--lowvram Режим экономии видеопамяти (~8 ГБ VRAM)
|
||||
--cpu Запуск на процессоре, без CUDA (очень медленно)
|
||||
--share Публичная ссылка Gradio
|
||||
--port <N> Порт веб-интерфейса (по умолчанию $PORT)
|
||||
--device <N> Номер видеокарты (по умолчанию $DEVICE_ID)
|
||||
--listen Слушать 0.0.0.0 (доступ из локальной сети)
|
||||
--reinstall Пересоздать виртуальное окружение с нуля
|
||||
--update Обновить зависимости
|
||||
--setup Только установка, без запуска
|
||||
--help Эта справка
|
||||
|
||||
Настройки по умолчанию — в блоке НАСТРОЙКИ в начале файла,
|
||||
их можно переопределить переменными окружения (PORT=7870 ./$SCRIPT_NAME).
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
die() {
|
||||
echo
|
||||
echo "[ОШИБКА] $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--help|-h) usage; exit 0 ;;
|
||||
--lowvram) OPT_LOWVRAM=1; shift ;;
|
||||
--cpu) OPT_CPU=1; shift ;;
|
||||
--share) OPT_SHARE=1; shift ;;
|
||||
--setup) DO_SETUP_ONLY=1; shift ;;
|
||||
--reinstall) DO_REINSTALL=1; shift ;;
|
||||
--update) DO_UPDATE=1; shift ;;
|
||||
--listen) SERVER_NAME="0.0.0.0"; shift ;;
|
||||
--port) PORT="${2:?--port требует значение}"; shift 2 ;;
|
||||
--device) DEVICE_ID="${2:?--device требует значение}"; shift 2 ;;
|
||||
*)
|
||||
echo "[ОШИБКА] Неизвестный аргумент: $1" >&2
|
||||
echo "Запустите ./$SCRIPT_NAME --help для справки." >&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo
|
||||
echo "=========================================="
|
||||
echo " ACE-Step - генерация музыки"
|
||||
echo "=========================================="
|
||||
echo
|
||||
|
||||
case "$(uname -s)" in
|
||||
Darwin) IS_MAC=1 ;;
|
||||
*) IS_MAC=0 ;;
|
||||
esac
|
||||
|
||||
VENV_PY="$PWD/$VENV_DIR/bin/python"
|
||||
|
||||
# Рабочим считаем окружение, в котором есть и python, и pip: каталог от
|
||||
# прерванной установки (или venv без ensurepip) выглядит как готовый, но валится
|
||||
# дальше с невнятной ошибкой.
|
||||
venv_ok() {
|
||||
[ -x "$VENV_PY" ] && "$VENV_PY" -m pip --version >/dev/null 2>&1
|
||||
}
|
||||
|
||||
venv_failed() {
|
||||
echo >&2
|
||||
echo "[ОШИБКА] Не удалось создать рабочее виртуальное окружение в \"$VENV_DIR\"." >&2
|
||||
if [ "$IS_MAC" = 0 ] && command -v apt >/dev/null 2>&1; then
|
||||
echo "На Debian/Ubuntu для этого нужен отдельный пакет:" >&2
|
||||
echo " sudo apt install python3-venv" >&2
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ "$DO_REINSTALL" = 1 ] && [ -d "$VENV_DIR" ]; then
|
||||
echo "[1/4] Удаляю старое окружение \"$VENV_DIR\"..."
|
||||
rm -rf "$VENV_DIR"
|
||||
fi
|
||||
|
||||
# ------------------------- поиск Python -------------------------
|
||||
if venv_ok; then
|
||||
echo "[1/4] Виртуальное окружение найдено: $VENV_DIR"
|
||||
else
|
||||
if [ -d "$VENV_DIR" ]; then
|
||||
echo "[1/4] Окружение \"$VENV_DIR\" неработоспособно, пересоздаю..."
|
||||
rm -rf "$VENV_DIR"
|
||||
fi
|
||||
echo "[1/4] Ищу подходящий Python..."
|
||||
SYS_PY=""
|
||||
for candidate in python3.12 python3.11 python3.10 python3.13 python3; do
|
||||
if command -v "$candidate" >/dev/null 2>&1 &&
|
||||
"$candidate" -c 'import sys; sys.exit(0 if sys.version_info >= (3,10) else 1)' 2>/dev/null; then
|
||||
SYS_PY="$candidate"
|
||||
break
|
||||
fi
|
||||
done
|
||||
[ -n "$SYS_PY" ] || die "Не найден Python 3.10 или новее. Установите его и повторите."
|
||||
|
||||
echo " Найден Python $("$SYS_PY" -c 'import sys; print(sys.version.split()[0])') ($SYS_PY)"
|
||||
echo "[1/4] Создаю виртуальное окружение в \"$VENV_DIR\"..."
|
||||
"$SYS_PY" -m venv "$VENV_DIR" || venv_failed
|
||||
venv_ok || venv_failed
|
||||
fi
|
||||
|
||||
# ------------------------- зависимости -------------------------
|
||||
echo "[2/4] Проверяю зависимости..."
|
||||
|
||||
NEED_TORCH=0
|
||||
"$VENV_PY" -c "import importlib.util,sys; sys.exit(0 if importlib.util.find_spec('torch') else 1)" 2>/dev/null || NEED_TORCH=1
|
||||
|
||||
# Проверяем именно установку пакета: каталог acestep лежит рядом со скриптом,
|
||||
# поэтому find_spec('acestep') сработал бы и без установленных зависимостей.
|
||||
NEED_ACESTEP=0
|
||||
"$VENV_PY" -c "import importlib.metadata as md, importlib.util as u, sys; md.version('ace_step'); sys.exit(0 if u.find_spec('click') and u.find_spec('gradio') else 1)" 2>/dev/null || NEED_ACESTEP=1
|
||||
|
||||
if [ "$DO_UPDATE" = 1 ]; then
|
||||
NEED_TORCH=1
|
||||
NEED_ACESTEP=1
|
||||
fi
|
||||
|
||||
if [ "$NEED_TORCH" = 1 ] || [ "$NEED_ACESTEP" = 1 ]; then
|
||||
echo " Обновляю pip..."
|
||||
"$VENV_PY" -m pip install --upgrade pip setuptools wheel --quiet ||
|
||||
die "Не удалось обновить pip. Проверьте подключение к интернету."
|
||||
fi
|
||||
|
||||
if [ "$NEED_TORCH" = 1 ]; then
|
||||
if [ "$IS_MAC" = 1 ]; then
|
||||
# На macOS колёса с PyPI уже собраны с поддержкой MPS.
|
||||
echo " Устанавливаю PyTorch (macOS/MPS). Это займёт несколько минут..."
|
||||
"$VENV_PY" -m pip install --upgrade torch torchvision torchaudio
|
||||
elif [ "$OPT_CPU" = 1 ]; then
|
||||
echo " Устанавливаю PyTorch для CPU. Это займёт несколько минут..."
|
||||
"$VENV_PY" -m pip install --upgrade torch torchvision torchaudio \
|
||||
--index-url https://download.pytorch.org/whl/cpu
|
||||
else
|
||||
echo " Устанавливаю PyTorch с поддержкой CUDA. Это займёт несколько минут..."
|
||||
"$VENV_PY" -m pip install --upgrade torch torchvision torchaudio --index-url "$TORCH_INDEX"
|
||||
fi || die "Не удалось установить PyTorch. Если у вас другая версия CUDA, поменяйте TORCH_INDEX."
|
||||
fi
|
||||
|
||||
if [ "$NEED_ACESTEP" = 1 ]; then
|
||||
echo " Устанавливаю ACE-Step и зависимости..."
|
||||
"$VENV_PY" -m pip install -e . || die "Не удалось установить ACE-Step."
|
||||
fi
|
||||
|
||||
if [ "$OPT_LOWVRAM" = 1 ] && [ "$IS_MAC" = 0 ]; then
|
||||
if ! "$VENV_PY" -c "import importlib.util,sys; sys.exit(0 if importlib.util.find_spec('triton') else 1)" 2>/dev/null; then
|
||||
echo " Режим экономии VRAM: устанавливаю triton..."
|
||||
"$VENV_PY" -m pip install triton --quiet ||
|
||||
echo "[ВНИМАНИЕ] triton не установился, --torch_compile может не заработать."
|
||||
fi
|
||||
fi
|
||||
|
||||
# ------------------------- проверка устройства -------------------------
|
||||
echo "[3/4] Проверяю устройство..."
|
||||
BF16=true
|
||||
if [ "$OPT_CPU" = 1 ]; then
|
||||
echo " Принудительный режим CPU. Генерация будет очень медленной."
|
||||
DEVICE_ID=-1
|
||||
BF16=false
|
||||
elif [ "$IS_MAC" = 1 ]; then
|
||||
# На MPS bfloat16 приводит к ошибкам, см. README.
|
||||
echo " macOS: используется MPS, bf16 отключён."
|
||||
BF16=false
|
||||
else
|
||||
GPUINFO="$("$VENV_PY" -c "import torch; print((torch.cuda.get_device_name(0) + ' - ' + str(round(torch.cuda.get_device_properties(0).total_memory/1073741824, 1)) + ' GB VRAM') if torch.cuda.is_available() else 'NO_CUDA')" 2>/dev/null || echo NO_CUDA)"
|
||||
if [ "$GPUINFO" = "NO_CUDA" ]; then
|
||||
echo
|
||||
echo "[ВНИМАНИЕ] CUDA недоступна - модель будет работать на процессоре (очень медленно)."
|
||||
echo "Если у вас есть видеокарта NVIDIA, обновите драйвер и переустановите PyTorch:"
|
||||
echo " ./$SCRIPT_NAME --update"
|
||||
echo
|
||||
else
|
||||
echo " $GPUINFO"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$DO_SETUP_ONLY" = 1 ]; then
|
||||
echo
|
||||
echo "Установка завершена. Для запуска выполните ./$SCRIPT_NAME"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ------------------------- запуск -------------------------
|
||||
ARGS=(--port "$PORT" --server_name "$SERVER_NAME" "--device_id=$DEVICE_ID" --bf16 "$BF16")
|
||||
[ -n "$CHECKPOINT_PATH" ] && ARGS+=(--checkpoint_path "$CHECKPOINT_PATH")
|
||||
[ "$OPT_SHARE" = 1 ] && ARGS+=(--share true)
|
||||
if [ "$OPT_LOWVRAM" = 1 ]; then
|
||||
ARGS+=(--cpu_offload true --overlapped_decode true)
|
||||
[ "$IS_MAC" = 0 ] && ARGS+=(--torch_compile true)
|
||||
fi
|
||||
|
||||
echo "[4/4] Запускаю веб-интерфейс..."
|
||||
echo
|
||||
[ "$OPT_LOWVRAM" = 1 ] && echo " Режим: экономия видеопамяти"
|
||||
echo " Идёт загрузка моделей, это занимает время."
|
||||
echo " При первом запуске дополнительно скачиваются веса (~8 ГБ)."
|
||||
echo
|
||||
echo " Интерфейс будет доступен на http://$SERVER_NAME:$PORT"
|
||||
echo " когда ниже появится строка \"Running on local URL\"."
|
||||
echo " Остановить: Ctrl+C в этом окне."
|
||||
echo
|
||||
|
||||
exec "$VENV_PY" -m acestep.gui "${ARGS[@]}"
|
||||
Reference in New Issue
Block a user