AI 실무 교재 TTS · 음성합성

Qwen-TTS 입문 매뉴얼

구글 코랩에서 설치하고, CustomVoice부터 사용해 보는 실습 교재

📚 15개 챕터 🐍 Python 코드 포함 🎙 TTS · 보이스 클로닝 ☁️ Google Colab 기준
CUSTOM VOICE
내장 화자 선택형
참조 음성 없이 모델에 내장된 화자를 선택해 바로 음성 생성. 가장 빠른 시작 방법.
입문 추천
BASE
보이스 클로닝형
참조 음성과 텍스트를 입력해 해당 화자의 목소리 스타일로 음성 생성.
심화 과정

1Qwen-TTS란?

Qwen-TTS는 Qwen 팀이 공개한 오픈소스 텍스트-투-스피치(TTS) 모델 시리즈다. 문장을 음성으로 바꾸는 기능뿐 아니라, 다음과 같은 기능을 지원한다.

  • 다국어 음성 합성
  • 자연어 지시를 통한 스타일 제어
  • 스트리밍 기반 저지연 합성
  • 참조 음성을 이용한 보이스 클로닝
  • 미리 준비된 화자를 사용하는 TTS

공식 자료 기준으로 Qwen3-TTS는 다음 10개 언어를 지원한다.

  • Chinese
  • English
  • Japanese
  • Korean
  • German
  • French
  • Russian
  • Portuguese
  • Spanish
  • Italian

2모델 종류 이해하기

Qwen-TTS는 크게 두 계열로 생각하면 쉽다.

2.1 CustomVoice

참조 음성을 넣지 않고, 모델에 내장된 화자(speaker)를 선택해서 바로 음성을 생성하는 방식이다.

이 방식은 다음 상황에 적합하다.

  • TTS를 빠르게 테스트하고 싶을 때
  • 보이스 클로닝 없이 바로 결과를 듣고 싶을 때
  • 코랩에서 가장 간단하게 시작하고 싶을 때

예:

  • Qwen/Qwen3-TTS-12Hz-0.6B-CustomVoice
  • Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice

2.2 Base

사용자가 제공한 참조 음성(ref_audio)참조 텍스트(ref_text)를 이용해, 그 화자의 목소리 스타일을 따라 음성을 생성하는 방식이다.

이 방식은 다음 상황에 적합하다.

  • 내 목소리 비슷하게 만들고 싶을 때
  • 특정 샘플 음성을 따라 읽게 하고 싶을 때
  • 보이스 클로닝이 필요할 때

예:

  • Qwen/Qwen3-TTS-12Hz-0.6B-Base
  • Qwen/Qwen3-TTS-12Hz-1.7B-Base

30.6B와 1.7B의 차이

모델 이름의 0.6B, 1.7B는 대략적인 모델 규모를 의미한다.

3.1 0.6B

장점:

  • 더 가볍다
  • 로딩이 빠르다
  • 코랩에서 시작하기 쉽다
  • 테스트용, 입문용으로 적합하다

단점:

  • 더 큰 모델보다 표현력의 여유가 적을 수 있다

3.2 1.7B

장점:

  • 더 큰 모델이라 음색 표현, 억양, 스타일 제어에서 여유가 있을 가능성이 높다
  • 장문이나 고품질 생성에서 기대치가 높다

단점:

  • 메모리 사용량이 더 크다
  • 다운로드와 로딩이 더 무겁다
  • 코랩 무료 GPU에서는 부담이 될 수 있다

3.3 추천

💡
처음 시작할 때는 보통 아래 조합이 가장 무난하다.
Qwen/Qwen3-TTS-12Hz-0.6B-CustomVoice

4구글 코랩에서 준비할 것

코랩에서 사용하려면 다음을 권장한다.

4.1 런타임 설정

상단 메뉴에서 다음으로 이동한다.

  1. 런타임
  2. 런타임 유형 변경
  3. 하드웨어 가속기: GPU
COLAB 메뉴 경로
런타임 런타임 유형 변경 하드웨어 가속기 : GPU
권장: T4 GPU 이상

4.2 왜 GPU가 좋은가?

Qwen-TTS 공식 예제는 GPU 사용을 기준으로 device_map="cuda:0" 형태를 자주 사용한다. CPU에서도 이론상 가능할 수 있지만, 속도와 메모리 측면에서 비효율적이다.

⚠️
런타임 설정 필수: GPU 없이 실행하면 속도가 매우 느리거나 오류가 날 수 있다. 반드시 T4 GPU 이상으로 설정하고 시작하자.

5설치 방법

Qwen-TTS 공식 Quickstart 기준 설치 명령은 다음과 같다.

bash
pip install -U qwen-tts

코랩에서는 보통 오디오 저장을 위해 soundfile도 함께 설치한다.

5.1 코랩 설치 셀

아래 코드 셀을 실행한다.

python
!pip install -U qwen-tts soundfile

5.2 선택 사항: FlashAttention

공식 문서에는 성능 최적화를 위해 다음 설치도 안내되어 있다. 하지만 코랩 환경에 따라 설치 실패가 날 수 있다. 입문 단계에서는 먼저 기본 설치만 하고, 필요할 때 추가하는 편이 좋다.

python
## 선택 사항
!pip install -U flash-attn --no-build-isolation
💡
FlashAttention은 선택 사항: 처음에는 없어도 동작한다. 설치가 실패하면 무시하고 넘어가면 된다.

6CustomVoice 빠른 시작

이 장에서는 가장 쉬운 시작점인 CustomVoice를 다룬다.

6.1 지원 화자

Qwen3-TTS-12Hz-0.6B-CustomVoice 기준으로 자주 쓰는 화자는 다음과 같다.

Vivian Serena Uncle_Fu Dylan Eric Ryan Aiden Ono_Anna Sohee
💡
한국어 테스트에는 Sohee가 가장 적합하다. 한국어 발음이 자연스럽게 출력된다.
python
import torch
import soundfile as sf
from qwen_tts import Qwen3TTSModel

model = Qwen3TTSModel.from_pretrained(
    "Qwen/Qwen3-TTS-12Hz-0.6B-CustomVoice",
    device_map="cuda:0",
    dtype=torch.bfloat16,
)

wavs, sr = model.generate_custom_voice(
    text="안녕하세요. 지금은 Qwen 커스텀보이스를 코랩에서 테스트하고 있습니다.",
    speaker="Sohee",
    language="Korean",
)

sf.write("customvoice_test.wav", wavs[0], sr)
print("saved:", sr, len(wavs[0]))
python
from IPython.display import Audio
Audio("customvoice_test.wav")

7스타일을 주어 말투 바꾸기

Qwen-TTS는 자연어 지시를 이용한 스타일 제어를 지원한다. 예를 들어 차분하게, 밝게, 뉴스 앵커처럼 같은 지시를 줄 수 있다.

python
import torch
import soundfile as sf
from qwen_tts import Qwen3TTSModel
from IPython.display import Audio

model = Qwen3TTSModel.from_pretrained(
    "Qwen/Qwen3-TTS-12Hz-0.6B-CustomVoice",
    device_map="cuda:0",
    dtype=torch.bfloat16,
)

wavs, sr = model.generate_custom_voice(
    text="오늘 발표를 시작하겠습니다. 끝까지 들어주셔서 감사합니다.",
    speaker="Sohee",
    language="Korean",
    instruct="차분하고 또렷하게, 약간 밝은 뉴스 앵커 톤으로 말해줘.",
)

sf.write("customvoice_style.wav", wavs[0], sr)
Audio("customvoice_style.wav")

스타일 지시문 예시:

  • 차분하고 부드럽게 말해줘.
  • 밝고 경쾌한 광고 톤으로 읽어줘.
  • 감정을 절제한 뉴스 진행자처럼 말해줘.
  • 조금 천천히, 또렷한 발음으로 말해줘.

8Base 모델 사용 방법

Base 모델은 참조 음성을 넣어서 보이스 클로닝을 할 때 사용한다.

8.1 기본 개념

아래 두 입력이 필요하다.

  • ref_audio: 참조 음성 파일
  • ref_text: 참조 음성에 실제로 들어 있는 텍스트

즉, 참조 음성을 모델에 주고, 그 음성의 특징을 따라 새 문장을 읽도록 하는 방식이다.

기존 녹음 파일 업로드 후 클론 보이스 생성

1. 설치

python
!pip install -U qwen-tts soundfile
!apt-get -y install ffmpeg

2. 모델 로드

python
import torch
from qwen_tts import Qwen3TTSModel

DEVICE = "cuda:0" if torch.cuda.is_available() else "cpu"
DTYPE = torch.bfloat16 if torch.cuda.is_available() else torch.float32

print("DEVICE:", DEVICE)
print("CUDA available:", torch.cuda.is_available())

model = Qwen3TTSModel.from_pretrained(
    "Qwen/Qwen3-TTS-12Hz-0.6B-Base",
    device_map=DEVICE,
    dtype=DTYPE,
)

3. 참조 텍스트 입력 + 파일 업로드 + 클론 생성

python
import os
import subprocess
import soundfile as sf
from google.colab import files
from IPython.display import Audio, display

print("=== Qwen-TTS Voice Clone: 파일 업로드 방식 ===")

# 1. 참조 문장 입력
ref_text = input("\n[1단계] 참조 음성 파일에 실제로 들어 있는 문장을 입력하세요:\n> ").strip()
if not ref_text:
    raise ValueError("참조 음성 문장을 입력해야 합니다.")

# 2. 파일 업로드
print("\n[2단계] 참조 음성 파일을 업로드하세요. (wav/mp3/m4a/webm 등)")
uploaded = files.upload()

if not uploaded:
    raise ValueError("업로드된 파일이 없습니다.")

uploaded_name = next(iter(uploaded.keys()))
src_path = f"/content/{uploaded_name}"
wav_path = "/content/reference_uploaded.wav"

# 3. wav 변환
subprocess.run([
    "ffmpeg", "-y",
    "-i", src_path,
    "-ac", "1",
    "-ar", "16000",
    wav_path
], check=True)

# 4. 길이 확인
audio, sr = sf.read(wav_path)
duration = len(audio) / sr
print(f"\n참조 음성 길이: {duration:.2f}초")

if duration < 3.0:
    print("안내: 참조 음성은 3초 이상을 권장합니다.")
else:
    print("참조 음성 길이가 적절합니다.")

# 5. 생성 문장 입력
target_text = input("\n[4단계] 생성할 음성 스크립트를 입력하세요:\n> ").strip()
if not target_text:
    raise ValueError("생성할 문장을 입력해야 합니다.")

# 6. 음성 생성
wavs, out_sr = model.generate_voice_clone(
    text=target_text,
    language="Korean",
    ref_audio=wav_path,
    ref_text=ref_text,
)

# 7. 저장 및 재생
out_path = "/content/voice_clone_from_upload.wav"
sf.write(out_path, wavs[0], out_sr)
print("\n음성 생성이 완료되었습니다.")
print("저장 위치:", out_path)
display(Audio(out_path))

코랩에서 직접 녹음 후 클론 보이스 생성

이 버전은 참조 문장을 먼저 입력하고, 코랩에서 직접 녹음 시작/중지해서 그 녹음을 참조 음성으로 씁니다.

1. 설치

python
!pip install -U qwen-tts soundfile
!apt-get -y install ffmpeg

2. 모델 로드

python
import torch
from qwen_tts import Qwen3TTSModel

DEVICE = "cuda:0" if torch.cuda.is_available() else "cpu"
DTYPE = torch.bfloat16 if torch.cuda.is_available() else torch.float32

model = Qwen3TTSModel.from_pretrained(
    "Qwen/Qwen3-TTS-12Hz-0.6B-Base",
    device_map=DEVICE,
    dtype=DTYPE,
)

3. 직접 녹음 → wav 변환 → 목소리 프로파일 저장

python
import os
import torch
import subprocess
import soundfile as sf
from dataclasses import asdict
from IPython.display import display, HTML, Javascript
from google.colab import output
from base64 import b64decode

print("=== Qwen-TTS Voice Clone: 직접 녹음 후 목소리 프로파일 저장 ===")

# 1. 참조 문장 입력
REF_TEXT = input("\n[1단계] 지금 읽어서 녹음할 참조 문장을 입력하세요:\n> ").strip()
if not REF_TEXT:
    raise ValueError("참조 문장을 먼저 입력해야 합니다.")

PROFILE_PATH = "/content/voice_clone_prompt.pt"

display(HTML(f"""
<div style="border:1px solid #ddd; padding:16px; border-radius:12px;">
  <h3>참조 음성 직접 녹음</h3>
  <p><b>읽을 문장:</b> {REF_TEXT}</p>
  <button id="start_btn">Start Recording</button>
  <button id="stop_btn" disabled>Stop Recording</button>
</div>
"""))

# ... (JavaScript 녹음 로직 포함)
# prepare_voice_profile 콜백으로 webm → wav 변환 및 프로파일 저장

4. 저장된 목소리 프로파일 불러오기 → TTS 생성

python
import torch
import soundfile as sf
from IPython.display import Audio, display
from qwen_tts.inference.qwen3_tts_model import VoiceClonePromptItem

PROFILE_PATH = "/content/voice_clone_prompt.pt"
OUT_PATH = "/content/voice_clone_from_profile.wav"

target_text = input("\n[5단계] 저장된 목소리로 읽을 문장을 입력하세요:\n> ").strip()

# 프로파일 로드
payload = torch.load(PROFILE_PATH, map_location="cpu", weights_only=True)
items_raw = payload["items"]

prompt_items = []
for d in items_raw:
    ref_spk = d.get("ref_spk_embedding", None)
    if not torch.is_tensor(ref_spk):
        ref_spk = torch.tensor(ref_spk)
    prompt_items.append(
        VoiceClonePromptItem(
            ref_spk_embedding=ref_spk,
            ref_text=d.get("ref_text", None),
        )
    )

# TTS 생성
wavs, out_sr = model.generate_voice_clone(
    text=target_text,
    language="Korean",
    voice_clone_prompt=prompt_items,
)

sf.write(OUT_PATH, wavs[0], out_sr)
display(Audio(OUT_PATH))

8.2 Base를 쓸 때 주의할 점

  • 참조 음성 품질이 좋아야 결과도 좋아진다
  • 배경 소음이 적은 음성이 유리하다
  • ref_text는 실제 음성과 최대한 일치해야 한다

9코랩에서 가장 추천하는 시작 순서

  1. 0.6B-CustomVoice로 시작한다.
  2. Sohee + Korean 조합으로 짧은 문장을 생성한다.
  3. instruct 옵션으로 말투를 바꿔 본다.
  4. 문장이 잘 나오면 Base 모델로 넘어가 보이스 클로닝을 실험한다.
추천 순서를 지키면 오류 없이 빠르게 결과를 볼 수 있다. Base 모델은 CustomVoice에 익숙해진 다음에 시도하자.

10자주 쓰는 전체 실행 코드

아래 코드는 CustomVoice를 코랩에서 한 번에 시험하기 위한 전체 예제다.

python
!pip install -U qwen-tts soundfile

import torch
import soundfile as sf
from qwen_tts import Qwen3TTSModel
from IPython.display import Audio

model = Qwen3TTSModel.from_pretrained(
    "Qwen/Qwen3-TTS-12Hz-0.6B-CustomVoice",
    device_map="cuda:0",
    dtype=torch.bfloat16,
)

text = "안녕하세요. 지금은 Qwen TTS 교재용 예제를 테스트하고 있습니다."

wavs, sr = model.generate_custom_voice(
    text=text,
    speaker="Sohee",
    language="Korean",
    instruct="차분하고 자연스럽게 읽어줘.",
)

sf.write("qwen_tts_output.wav", wavs[0], sr)
Audio("qwen_tts_output.wav")

11자주 발생하는 오류와 해결법

11.1 GPU 관련 오류

오류 예시:
CUDA is not available
device_map="cuda:0" 관련 오류

원인: 코랩 런타임이 CPU로 되어 있음

해결: 런타임 유형을 GPU로 바꾼다

python
import torch
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else "No GPU")

11.2 메모리 부족 오류

오류 예시: CUDA out of memory

원인:

  • 1.7B 모델이 현재 GPU 환경에 비해 무거움
  • 여러 번 생성하면서 메모리가 누적됨

해결:

  • 0.6B 모델부터 사용한다
  • 런타임 다시 시작 후 재실행한다
  • 긴 문장을 짧게 나눠 생성한다

11.3 FlashAttention 설치 실패

⚠️
원인: 코랩의 CUDA / torch / wheel 조합이 맞지 않음
해결: flash-attn 없이 먼저 실행한다. 최적화는 나중에 시도한다.

11.4 speaker 이름 오류

원인: 지원하지 않는 화자 이름을 넣음 / 대소문자, 언더스코어를 다르게 입력함

해결: 공식 화자 이름을 그대로 사용한다.

  • Sohee
  • Ono_Anna
  • Uncle_Fu

12어떤 모델을 고르면 좋은가?

🚀
빠르게 시작하고 싶다
Qwen3-TTS-12Hz-0.6B-CustomVoice
🎭
내장 화자로 감정 표현까지 써 보고 싶다
0.6B-CustomVoice / 필요 시 1.7B-CustomVoice
🎙
특정 사람 목소리를 비슷하게 만들고 싶다
Qwen3-TTS-12Hz-0.6B-Base / 필요 시 1.7B-Base

13추천 학습 흐름

아래 순서로 단계별로 진행하면 막힘 없이 익힐 수 있다.

1설치
2CustomVoice 최소 예제 실행
3한국어 화자 Sohee 테스트
4instruct 스타일 변경
5장문 생성 실험
6Base 모델 보이스 클로닝

14참고 요약

📋 핵심 정리

  • qwen-tts로 설치한다
  • 가장 쉬운 시작은 0.6B-CustomVoice
  • 한국어 테스트에는 speaker="Sohee"가 편하다
  • language="Korean"을 사용한다
  • 스타일 제어는 instruct로 줄 수 있다
  • 보이스 클로닝은 Base 모델로 한다

15마무리

Qwen-TTS는 입문자 기준으로도 비교적 시작이 쉬운 편이다. 특히 CustomVoice는 별도 참조 음성 없이도 결과를 바로 들어볼 수 있어서, TTS 모델을 처음 익히는 사람에게 좋은 출발점이 된다.

처음에는 아래 한 줄만 기억해도 충분하다.

✅ 한 줄 요약

  • 설치: pip install -U qwen-tts
  • 시작 모델: Qwen/Qwen3-TTS-12Hz-0.6B-CustomVoice
  • 한국어 화자: Sohee
이제 시작할 준비가 됐다! CustomVoice부터 실행해 보고, 결과가 마음에 들면 Base 모델로 확장해 보자.