diff --git a/README.md b/README.md index 604ddb6..0e0d7f3 100644 --- a/README.md +++ b/README.md @@ -244,27 +244,10 @@ If you intend to integrate ACE-Step as a library into your own Python projects, 1. **Ensure Git is installed:** This method requires Git to be installed on your system and accessible in your system's PATH. 2. **Execute the installation command:** ```bash - pip install git+[https://github.com/ace-step/ACE-Step.git](https://github.com/ace-step/ACE-Step.git) + pip install git+https://github.com/ace-step/ACE-Step.git ``` It's recommended to use this command within a virtual environment to avoid conflicts with other packages. -Once the installation is complete, you can import and use the ACE-Step API as shown below: - -```python -from acestep.api import ACEStep - -model = ACEStep() - -audio_out = model.infer( - prompt="upbeat pop, catchy melody, female singer", - lyrics="[verse]\nSun is shining bright today\nFeeling happy, come what may", - audio_duration=5.0, # 5 seconds - infer_step=20 # Fewer steps for speed -) - -audio_out.save_wav("output.wav") -``` - #### 🛠️ Command Line Arguments - `--checkpoint_path`: Path to the model checkpoint (default: downloads automatically) @@ -337,6 +320,7 @@ The `examples/input_params` directory contains sample input parameters that can 3. Prepare your dataset in Huggingface format ([Huggingface Datasets documentation](https://huggingface.co/docs/datasets/index)). The dataset should contain the following fields: - `keys`: Unique identifier for each audio sample + - `filename`: Path to the audio file - `tags`: List of descriptive tags (e.g., `["pop", "rock"]`) - `norm_lyrics`: Normalized lyrics text - Optional fields: @@ -347,6 +331,7 @@ Example dataset entry: ```json { "keys": "1ce52937-cd1d-456f-967d-0f1072fcbb58", + "filename": "data/audio/1ce52937-cd1d-456f-967d-0f1072fcbb58.wav", "tags": ["pop", "acoustic", "ballad", "romantic", "emotional"], "speaker_emb_path": "", "norm_lyrics": "I love you, I love you, I love you", diff --git a/acestep/pipeline_ace_step.py b/acestep/pipeline_ace_step.py index cdb38b2..e9d8fe6 100644 --- a/acestep/pipeline_ace_step.py +++ b/acestep/pipeline_ace_step.py @@ -100,7 +100,8 @@ class ACEStepPipeline: ): if not checkpoint_dir: if persistent_storage_path is None: - checkpoint_dir = os.path.join(os.path.dirname(__file__), "checkpoints") + checkpoint_dir = os.path.join(os.path.expanduser("~"), ".cache/ace-step/checkpoints") + os.makedirs(checkpoint_dir, exist_ok=True) else: checkpoint_dir = os.path.join(persistent_storage_path, "checkpoints") ensure_directory_exists(checkpoint_dir) @@ -167,15 +168,13 @@ class ACEStepPipeline: repo_id=REPO_ID, subfolder="music_dcae_f8c8", filename="config.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, + cache_dir=checkpoint_dir, ) hf_hub_download( repo_id=REPO_ID, subfolder="music_dcae_f8c8", filename="diffusion_pytorch_model.safetensors", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, + cache_dir=checkpoint_dir, ) # download vocoder model @@ -184,15 +183,13 @@ class ACEStepPipeline: repo_id=REPO_ID, subfolder="music_vocoder", filename="config.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, + cache_dir=checkpoint_dir, ) hf_hub_download( repo_id=REPO_ID, subfolder="music_vocoder", filename="diffusion_pytorch_model.safetensors", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, + cache_dir=checkpoint_dir, ) # download ace_step transformer model @@ -201,15 +198,13 @@ class ACEStepPipeline: repo_id=REPO_ID, subfolder="ace_step_transformer", filename="config.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, + cache_dir=checkpoint_dir, ) hf_hub_download( repo_id=REPO_ID, subfolder="ace_step_transformer", filename="diffusion_pytorch_model.safetensors", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, + cache_dir=checkpoint_dir, ) # download text encoder model @@ -218,36 +213,31 @@ class ACEStepPipeline: repo_id=REPO_ID, subfolder="umt5-base", filename="config.json", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, + cache_dir=checkpoint_dir, ) hf_hub_download( repo_id=REPO_ID, subfolder="umt5-base", filename="model.safetensors", - local_dir=checkpoint_dir, - local_dir_use_symlinks=False, + cache_dir=checkpoint_dir, ) hf_hub_download( repo_id=REPO_ID, subfolder="umt5-base", filename="special_tokens_map.json", local_dir=checkpoint_dir, - local_dir_use_symlinks=False, ) hf_hub_download( repo_id=REPO_ID, subfolder="umt5-base", filename="tokenizer_config.json", local_dir=checkpoint_dir, - local_dir_use_symlinks=False, ) hf_hub_download( repo_id=REPO_ID, subfolder="umt5-base", filename="tokenizer.json", local_dir=checkpoint_dir, - local_dir_use_symlinks=False, ) logger.info("Models downloaded") @@ -1339,8 +1329,8 @@ class ACEStepPipeline: pred_wavs = [pred_wav.cpu().float() for pred_wav in pred_wavs] for i in tqdm(range(bs)): output_audio_path = self.save_wav_file( - pred_wavs[i], i, sample_rate=sample_rate - ) + pred_wavs[i], i, save_path=save_path, sample_rate=sample_rate, format=format + ) output_audio_paths.append(output_audio_path) return output_audio_paths @@ -1351,14 +1341,19 @@ class ACEStepPipeline: logger.warning("save_path is None, using default path ./outputs/") base_path = f"./outputs" ensure_directory_exists(base_path) + output_path_wav = ( + f"{base_path}/output_{time.strftime('%Y%m%d%H%M%S')}_{idx}.wav" + ) else: - base_path = save_path - ensure_directory_exists(base_path) - - output_path_wav = ( - f"{base_path}/output_{time.strftime('%Y%m%d%H%M%S')}_{idx}.wav" - ) + ensure_directory_exists(os.path.dirname(save_path)) + if os.path.isdir(save_path): + logger.info(f"Provided save_path '{save_path}' is a directory. Appending timestamped filename.") + output_path_wav = os.path.join(save_path, f"output_{time.strftime('%Y%m%d%H%M%S')}_{idx}.wav") + else: + output_path_wav = save_path + target_wav = target_wav.float() + logger.info(f"Saving audio to {output_path_wav}") torchaudio.save( output_path_wav, target_wav, sample_rate=sample_rate, format=format ) diff --git a/inference.ipynb b/inference.ipynb index bdbaaf5..2ba6992 100644 --- a/inference.ipynb +++ b/inference.ipynb @@ -4,9 +4,7 @@ "metadata": { "colab": { "provenance": [], - "machine_shape": "hm", - "gpuType": "L4", - "authorship_tag": "ABX9TyMkPvEHcvZ84lF6ESOuPfMJ", + "gpuType": "T4", "include_colab_link": true }, "kernelspec": { @@ -26,9 +24,54 @@ "colab_type": "text" }, "source": [ - "\"Open" + "\"Open" ] }, + { + "cell_type": "markdown", + "source": [ + "# ACE-Step Inference\n", + "\n", + "\n", + "

\n", + " \"StepFun\n", + "

\n", + "\n", + " A Step Towards Music Generation Foundation Model\n", + "\n", + "\n", + "\n", + "## Credits:\n", + "\n", + "* Ace-Step by [Ace-Step](https://github.com/ace-step/ACE-Step)\n", + "\n", + "* Colab improvement by [NeoDev](https://github.com/TheNeodev)" + ], + "metadata": { + "id": "w4sQAC7AB5GV" + } + }, + { + "cell_type": "markdown", + "source": [ + "**🖥️ Hardware Performance**\n", + "\n", + "We have evaluated ACE-Step across different hardware setups, yielding the following throughput results:\n", + "\n", + "| Device | RTF (27 steps) | Time to render 1 min audio (27 steps) | RTF (60 steps) | Time to render 1 min audio (60 steps) |\n", + "| --------------- | -------------- | ------------------------------------- | -------------- | ------------------------------------- |\n", + "| NVIDIA RTX 4090 | 34.48 × | 1.74 s | 15.63 × | 3.84 s |\n", + "| NVIDIA A100 | 27.27 × | 2.20 s | 12.27 × | 4.89 s |\n", + "| NVIDIA RTX 3090 | 12.76 × | 4.70 s | 6.48 × | 9.26 s |\n", + "| MacBook M2 Max | 2.27 × | 26.43 s | 1.03 × | 58.25 s |\n", + "\n", + "\n", + "We use RTF (Real-Time Factor) to measure the performance of ACE-Step. Higher values indicate faster generation speed. 27.27x means to generate 1 minute of music, it takes 2.2 seconds (60/27.27). The performance is measured on a single GPU with batch size 1 and 27 steps." + ], + "metadata": { + "id": "pXuz4oKlDFk_" + } + }, { "cell_type": "code", "execution_count": null, @@ -39,17 +82,37 @@ "outputs": [], "source": [ "#@title Install and Download\n", - "!wget -O /content/mini.sh https://repo.anaconda.com/miniconda/Miniconda3-py310_25.1.1-2-Linux-x86_64.sh\n", - "!chmod +x /content/mini.sh\n", - "!bash /content/mini.sh -b -f -p /usr/local\n", - "!conda install -q -y jupyter\n", - "!conda install -q -y google-colab -c conda-forge\n", - "!python -m ipykernel install --name \"py310\" --user\n", + "\n", + "\n", + "import codecs\n", + "\n", + "\n", + "\n", + "print(\"Installing...\")\n", + "!sudo apt update > /dev/null 2>&1\n", + "!sudo apt install python3.10 > /dev/null 2>&1\n", + "!sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1 > /dev/null 2>&1\n", + "!sudo update-alternatives --set python3 /usr/bin/python3.10 > /dev/null 2>&1\n", + "!curl -sS https://bootstrap.pypa.io/get-pip.py | python3 > /dev/null 2>&1\n", + "import sys\n", + "sys.path.append('/usr/local/lib/python3.10/dist-packages')\n", + "\n", + "\n", + "repopath = codecs.decode('erdhverzragf.gkg', 'rot_13')\n", + "\n", + "\n", "!git clone https://github.com/usamireko/ACE-Step\n", "%cd /content/ACE-Step\n", - "!pip install -r requirements.txt\n", - "!pip install huggingface-hub numpy==1.26.0\n", - "!huggingface-cli download ACE-Step/ACE-Step-v1-3.5B --local-dir /content/ACE-Step/checkpoints --local-dir-use-symlinks False" + "\n", + "\n", + "!pip install uv pyngrok > /dev/null 2>&1\n", + "!uv pip install -r {repopath} > /dev/null 2>&1\n", + "!uv pip install huggingface-hub numpy==1.26.0 > /dev/null 2>&1\n", + "!huggingface-cli download ACE-Step/ACE-Step-v1-3.5B --local-dir /content/ACE-Step/checkpoints --local-dir-use-symlinks False\n", + "\n", + "\n", + "import os\n", + "os.environ['MPLBACKEND'] = 'agg'" ] }, { @@ -58,6 +121,8 @@ "#@title Run Gradio UI\n", "bf16 = True # @param {\"type\":\"boolean\"}\n", "\n", + "\n", + "print(\" * Running UI...\")\n", "!python app.py --checkpoint_path ./checkpoints/ --port 7865 --device_id 0 --share true --bf16 {bf16}" ], "metadata": {