# Stable Audio

Stable Audio는 Zach Evans 외의 연구자들이 [Stable Audio Open](https://huggingface.co/papers/2407.14358)에서 제안했습니다. 텍스트 프롬프트를 입력으로 받아 이에 해당하는 사운드 또는 음악 샘플을 예측합니다.

Stable Audio Open은 텍스트 프롬프트에서 가변 길이(최대 47초)의 44.1kHz 스테레오 오디오를 생성합니다. 이 모델은 세 가지 구성 요소로 이루어져 있습니다. 웨이브폼을 관리 가능한 시퀀스 길이로 압축하는 오토인코더, 텍스트 조건화에 사용되는 T5 기반 텍스트 임베딩, 그리고 오토인코더의 잠재 공간에서 작동하는 트랜스포머 기반 확산(DiT) 모델입니다.

Stable Audio는 약 48k개의 오디오 녹음으로 구성된 코퍼스에서 학습되며, 이 중 약 47k개는 Freesound에서, 나머지는 Free Music Archive(FMA)에서 가져왔습니다. 모든 오디오 파일은 CC0, CC BY 또는 CC Sampling+ 라이선스에 따라 배포됩니다. 이 데이터는 autoencoder와 DiT를 학습하는 데 사용됩니다.

해당 논문의 초록은 다음과 같습니다: *오픈 생성 모델은 커뮤니티에 매우 중요하며, 파인튜닝을 가능하게 하고 새로운 모델을 제시할 때 베이스라인으로 기능합니다. 그러나 현재 대부분의 텍스트-오디오 모델은 비공개이며, 예술가와 연구자가 이를 기반으로 구축할 수 없습니다. 여기서는 Creative Commons 데이터로 학습된 새로운 오픈 웨이트 텍스트-오디오 모델의 아키텍처와 학습 과정을 설명합니다. 우리의 평가에 따르면, 이 모델의 성능은 다양한 지표에서 최첨단 수준과 경쟁적입니다. 특히, 보고된 FDopenl3 결과(생성물의 현실성을 측정)는 44.1kHz에서 고품질 스테레오 사운드 합성을 위한 잠재력을 보여줍니다.*

이 파이프라인은 [Yoach Lacombe](https://huggingface.co/ylacombe)님이 기여했습니다. 원본 코드베이스는 [Stability-AI/stable-audio-tools](https://github.com/Stability-AI/stable-audio-tools)에서 찾을 수 있습니다.

## 팁

프롬프트를 구성할 때 다음 사항을 기억하세요:

* 설명적인 프롬프트 입력이 가장 효과적입니다. 형용사를 사용하여 사운드를 설명하고(예: "고품질" 또는 "명확한"), 가능한 한 프롬프트의 맥락을 구체적으로 작성하세요(예: "테크노"보다 "빠른 비트와 신스를 가진 멜로딕 테크노"가 더 효과적입니다).
* *negative prompt*를 사용하면 생성된 오디오의 품질을 크게 향상시킬 수 있습니다. "low quality, average quality"를 negative prompt로 사용해 보세요.

추론 중:

* 생성된 오디오 샘플의 _품질_은 `num_inference_steps` 인자로 제어할 수 있습니다. 단계 수가 높을수록 추론 속도는 느려지지만 더 높은 품질의 오디오를 얻을 수 있습니다.
* `num_waveforms_per_prompt`을 1보다 큰 값으로 설정하면 한 번에 여러 웨이브폼을 생성할 수 있습니다. 생성된 웨이브폼과 프롬프트 텍스트 사이에 자동 점수가 매겨지며, 점수에 따라 오디오가 우수도순으로 정렬됩니다.

## 양자화

Quantization은 모델 가중치를 더 낮은 정밀도의 데이터 타입으로 저장하여 매우 큰 모델의 메모리 요구 사항을 줄이는 데 도움이 됩니다. 그러나 quantization은 비디오 모델에 따라 비디오 품질에 다양한 영향을 미칠 수 있습니다.

지원되는 양자화 백엔드와 사용 사례에 맞는 양자화 백엔드 선택에 대해 자세히 알아보려면 [Quantization](../../quantization/overview) 개요를 참조하세요. 아래 예제는 bitsandbytes를 사용하여 추론을 위해 양자화된 [StableAudioPipeline](/docs/diffusers/main/ko/api/pipelines/stable_audio#diffusers.StableAudioPipeline)을 로드하는 방법을 보여줍니다.

```py
import torch
from diffusers import BitsAndBytesConfig as DiffusersBitsAndBytesConfig, StableAudioDiTModel, StableAudioPipeline
from diffusers.utils import export_to_video
from transformers import BitsAndBytesConfig as BitsAndBytesConfig, T5EncoderModel

quant_config = BitsAndBytesConfig(load_in_8bit=True)
text_encoder_8bit = T5EncoderModel.from_pretrained(
    "stabilityai/stable-audio-open-1.0",
    subfolder="text_encoder",
    quantization_config=quant_config,
    dtype=torch.float16,
)

quant_config = DiffusersBitsAndBytesConfig(load_in_8bit=True)
transformer_8bit = StableAudioDiTModel.from_pretrained(
    "stabilityai/stable-audio-open-1.0",
    subfolder="transformer",
    quantization_config=quant_config,
    dtype=torch.float16,
)

pipeline = StableAudioPipeline.from_pretrained(
    "stabilityai/stable-audio-open-1.0",
    text_encoder=text_encoder_8bit,
    transformer=transformer_8bit,
    dtype=torch.float16,
    device_map="balanced",
)

prompt = "The sound of a hammer hitting a wooden surface."
negative_prompt = "Low quality."
audio = pipeline(
    prompt,
    negative_prompt=negative_prompt,
    num_inference_steps=200,
    audio_end_in_s=10.0,
    num_waveforms_per_prompt=3,
    generator=generator,
).audios

output = audio[0].T.float().cpu().numpy()
sf.write("hammer.wav", output, pipeline.vae.sampling_rate)
```

## StableAudioPipeline[[diffusers.StableAudioPipeline]]

#### diffusers.StableAudioPipeline[[diffusers.StableAudioPipeline]]

```python
diffusers.StableAudioPipeline(vae: AutoencoderOobleck, text_encoder: T5EncoderModel, projection_model: StableAudioProjectionModel, tokenizer: T5Tokenizer, transformer: StableAudioDiTModel, scheduler: EDMDPMSolverMultistepScheduler)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_audio/pipeline_stable_audio.py#L78)

**매개변수:**

vae ([AutoencoderOobleck](/docs/diffusers/main/ko/api/models/autoencoder_oobleck#diffusers.AutoencoderOobleck)) : 이미지를 잠재 표현으로 인코딩하고 디코딩하는 Variational Auto-Encoder (VAE) 모델.

text_encoder ([T5EncoderModel](https://huggingface.co/docs/transformers/main/en/model_doc/t5#transformers.T5EncoderModel)) : 고정된 텍스트 인코더입니다. StableAudio는 [T5](https://huggingface.co/docs/transformers/model_doc/t5#transformers.T5EncoderModel)의 인코더, 구체적으로 [google-t5/t5-base](https://huggingface.co/google-t5/t5-base) 변형을 사용합니다.

projection_model (`StableAudioProjectionModel`) : 텍스트 인코더 모델의 hidden-states와 시작 및 종료 초를 선형적으로 투사하는 데 사용되는 학습된 모델입니다. 인코더의 투사된 hidden-states와 조건부 초가 연결되어(transformer 모델의 입력으로) transformer 모델의 입력을 구성합니다.

tokenizer ([T5Tokenizer](https://huggingface.co/docs/transformers/main/en/model_doc/t5#transformers.T5Tokenizer)) : 동결된 text-encoder에 사용할 텍스트를 토큰화하는 Tokenizer입니다.

transformer ([StableAudioDiTModel](/docs/diffusers/main/ko/api/models/stable_audio_transformer#diffusers.StableAudioDiTModel)) : 인코딩된 오디오 잠재 변수의 노이즈를 제거하기 위한 `StableAudioDiTModel`입니다.

scheduler ([EDMDPMSolverMultistepScheduler](/docs/diffusers/main/ko/api/schedulers/edm_multistep_dpm_solver#diffusers.EDMDPMSolverMultistepScheduler)) : `transformer`와 함께 사용되어 인코딩된 오디오 잠재를 디노이즈하는 스케줄러입니다.

StableAudio를 사용한 텍스트-오디오 생성을 위한 Pipeline

이 모델은 [DiffusionPipeline](/docs/diffusers/main/ko/api/pipelines/overview#diffusers.DiffusionPipeline)에서 상속됩니다. 모든 파이프라인에 대해 구현된 일반적 메서드(다운로드, 저장, 특정 디바이스에서 실행 등)에 대해서는 상위 클래스 문서를 확인하세요.

#### __호출__[[diffusers.StableAudioPipeline.__call__]]

```python
__call__(prompt: str | list[str] = None, audio_end_in_s: float | None = None, audio_start_in_s: float | None = 0.0, num_inference_steps: int = 100, guidance_scale: float = 7.0, negative_prompt: str | list[str] | None = None, num_waveforms_per_prompt: int | None = 1, eta: float = 0.0, generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = None, latents: typing.Optional[torch.Tensor] = None, initial_audio_waveforms: typing.Optional[torch.Tensor] = None, initial_audio_sampling_rate: typing.Optional[torch.Tensor] = None, prompt_embeds: typing.Optional[torch.Tensor] = None, negative_prompt_embeds: typing.Optional[torch.Tensor] = None, attention_mask: typing.Optional[torch.LongTensor] = None, negative_attention_mask: typing.Optional[torch.LongTensor] = None, return_dict: bool = True, callback: typing.Optional[typing.Callable[[int, int, torch.Tensor], NoneType]] = None, callback_steps: int | None = 1, output_type: str | None = 'pt')
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_audio/pipeline_stable_audio.py#L462)

**매개변수:**

prompt (`str` 또는 `list[str]`, *선택 사항*) : 오디오 생성을 안내할 프롬프트입니다. 정의되지 않은 경우 `prompt_embeds`를 전달해야 합니다.

audio_end_in_s (`float`, *선택 사항*, 기본값 47.55) : 초 단위의 오디오 종료 인덱스.

audio_start_in_s (`float`, *선택 사항*, 기본값 0) : 초 단위의 오디오 시작 인덱스.

num_inference_steps (`int`, *선택 사항*, 기본값 100) : 디노이징 단계의 수입니다. 디노이징 단계가 많을수록 추론 속도가 느려지는 대신 일반적으로 더 높은 품질의 오디오를 생성합니다.

guidance_scale (`float`, *선택 사항*, 기본값 7.0) : guidance scale 값이 높을수록 모델은 텍스트 `prompt`와 밀접하게 연결된 오디오를 생성하도록 유도되지만, 음질 저하가 발생할 수 있습니다. `guidance_scale > 1`일 때 guidance scale이 활성화됩니다.

negative_prompt (`str` 또는 `list[str]`, *선택 사항*) : 오디오 생성에서 포함하지 않을 내용을 안내하는 프롬프트입니다. 정의되지 않은 경우 대신 `negative_prompt_embeds`를 전달해야 합니다. 가이던스를 사용하지 않을 때(`guidance_scale < 1`)에는 무시됩니다.

num_waveforms_per_prompt (`int`, *선택 사항*, 기본값 1) : 프롬프트당 생성할 웨이브폼의 수입니다.

eta (`float`, *선택 사항*, 기본값 0.0) : [DDIM](https://huggingface.co/papers/2010.02502) 논문에서 정의한 파라미터 eta (η)에 해당합니다. [DDIMScheduler](/docs/diffusers/main/ko/api/schedulers/ddim#diffusers.DDIMScheduler)에만 적용되며, 다른 스케줄러에서는 무시됩니다.

generator (`torch.Generator` 또는 `list[torch.Generator]`, *선택 사항*) : 생성을 결정적으로 만들기 위한 [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html)입니다.

latents (`torch.Tensor`, *선택 사항*) : 가우시안 분포에서 샘플링된 사전 생성된 노이즈된 latents로, 오디오 생성의 입력으로 사용됩니다. 동일한 생성을 다른 프롬프트로 조정하는 데 사용할 수 있습니다. 제공되지 않으면, 제공된 랜덤 `generator`를 사용하여 샘플링하여 latents 텐서를 생성합니다.

initial_audio_waveforms (`torch.Tensor`, *선택 사항*) : 생성을 위한 초기 오디오 웨이브폼으로 사용할 선택적 초기 오디오 웨이브폼입니다. `batch_size`는 모델에 전달된 프롬프트의 수에 해당하며, 형태는 `(batch_size, num_channels, audio_length)` 또는 `(batch_size, audio_length)`여야 합니다.

initial_audio_sampling_rate (`int`, *선택 사항*) : `initial_audio_waveforms`가 제공된 경우의 샘플링 레이트입니다. 모델과 동일해야 합니다.

prompt_embeds (`torch.Tensor`, *선택 사항*) : 텍스트 인코더 모델에서 사전 계산된 텍스트 임베딩입니다. *예를 들어* 프롬프트 가중치 설정과 같은 텍스트 입력을 쉽게 조정하는 데 사용할 수 있습니다. 제공되지 않으면 `prompt` 입력 인수에서 텍스트 임베딩이 계산됩니다.

negative_prompt_embeds (`torch.Tensor`, *선택 사항*) : 텍스트 인코더 모델에서 사전 계산된 부정 텍스트 임베딩입니다. *e.g.* 프롬프트 가중치와 같은 텍스트 입력을 쉽게 조정하는 데 사용할 수 있습니다. 제공되지 않으면 `negative_prompt` 입력 인수에서 negative_prompt_embeds가 계산됩니다.

attention_mask (`torch.LongTensor`, *선택 사항*) : `prompt_embeds`에 적용할 사전 계산된 attention mask입니다. 제공되지 않으면 `prompt` 입력 인자로부터 attention mask가 계산됩니다.

negative_attention_mask (`torch.LongTensor`, *선택 사항*) : `negative_text_audio_duration_embeds`에 적용할 사전 계산된 어텐션 마스크입니다.

return_dict (`bool`, *선택 사항*, 기본값 `True`) : 일반 튜플 대신 [StableDiffusionPipelineOutput](/docs/diffusers/main/ko/api/pipelines/stable_diffusion/img2img#diffusers.pipelines.stable_diffusion.StableDiffusionPipelineOutput)을 반환할지 여부.

callback (`Callable`, *선택 사항*) : 추론 중 `callback_steps` 단계마다 호출되는 함수입니다. 이 함수는 다음 인수를 받아 호출됩니다: `callback(step: int, timestep: int, latents: torch.Tensor)`.

callback_steps (`int`, *선택 사항*, 기본값 1) : `callback` 함수가 호출되는 주기입니다. 지정하지 않으면 모든 단계에서 콜백이 호출됩니다.

output_type (`str`, *선택 사항*, 기본값 `"pt"`) : 생성된 오디오의 출력 형식입니다. NumPy `np.ndarray`를 반환하려면 `"np"`를, PyTorch `torch.Tensor` 객체를 반환하려면 `"pt"`를 선택합니다. Latent diffusion model (LDM) 출력을 반환하려면 `"latent"`로 설정합니다.

**반환값:** [StableDiffusionPipelineOutput](/docs/diffusers/main/ko/api/pipelines/stable_diffusion/img2img#diffusers.pipelines.stable_diffusion.StableDiffusionPipelineOutput) 또는 `tuple`

`return_dict`가 `True`인 경우 [StableDiffusionPipelineOutput](/docs/diffusers/main/ko/api/pipelines/stable_diffusion/img2img#diffusers.pipelines.stable_diffusion.StableDiffusionPipelineOutput)가 반환되고, 그렇지 않으면 생성된 오디오를 포함하는 리스트가 첫 번째 요소인 `tuple`이 반환됩니다.

생성을 위한 pipeline의 호출 함수.

예:
```py
>>> import scipy
>>> import torch
>>> import soundfile as sf
>>> from diffusers import StableAudioPipeline

>>> repo_id = "stabilityai/stable-audio-open-1.0"
>>> pipe = StableAudioPipeline.from_pretrained(repo_id, torch_dtype=torch.float16)
>>> pipe = pipe.to("cuda")

>>> # define the prompts
>>> prompt = "The sound of a hammer hitting a wooden surface."
>>> negative_prompt = "Low quality."

>>> # set the seed for generator
>>> generator = torch.Generator("cuda").manual_seed(0)

>>> # run the generation
>>> audio = pipe(
...     prompt,
...     negative_prompt=negative_prompt,
...     num_inference_steps=200,
...     audio_end_in_s=10.0,
...     num_waveforms_per_prompt=3,
...     generator=generator,
... ).audios

>>> output = audio[0].T.float().cpu().numpy()
>>> sf.write("hammer.wav", output, pipe.vae.sampling_rate)
```

