Transformers documentation
Chuyển văn bản thành giọng nói
Chuyển văn bản thành giọng nói
Text-to-speech (TTS) là nhiệm vụ tạo ra giọng nói tự nhiên từ văn bản, trong đó giọng nói có thể được tạo ra bằng nhiều ngôn ngữ và cho nhiều người nói khác nhau. Hiện tại có một số mô hình text-to-speech khả dụng trong 🤗 Transformers, chẳng hạn như Dia, CSM, Bark, MMS, VITS và SpeechT5.
Bạn có thể dễ dàng tạo âm thanh bằng pipeline "text-to-audio" (hoặc tên gọi khác của nó - "text-to-speech").
Dưới đây là một ví dụ về cách sử dụng pipeline "text-to-speech" với CSM:
>>> from transformers import pipeline
>>> pipe = pipeline("text-to-audio", model="sesame/csm-1b")
>>> output = pipe("Hello from Sesame.")Dưới đây là một đoạn mã bạn có thể sử dụng để nghe âm thanh kết quả trong notebook:
>>> from IPython.display import Audio
>>> Audio(output["audio"], rate=output["sampling_rate"])Mặc định, CSM sử dụng giọng nói ngẫu nhiên. Bạn có thể thực hiện nhân bản giọng nói bằng cách cung cấp một tệp âm thanh tham chiếu như một phần của từ điển mẫu trò chuyện:
>>> import soundfile as sf
>>> import torch
>>> from datasets import Audio, load_dataset
>>> from transformers import pipeline
>>> pipe = pipeline("text-to-audio", model="sesame/csm-1b")
>>> ds = load_dataset("hf-internal-testing/dailytalk-dummy", split="train")
>>> ds = ds.cast_column("audio", Audio(sampling_rate=24000))
>>> conversation = [
... {
... "role": "0",
... "content": [
... {"type": "text", "text": "What are you working on?"},
... {"type": "audio", "path": ds[0]["audio"]["array"]},
... ],
... },
... {"role": "0", "content": [{"type": "text", "text": "How much money can you spend?"}]},
... ]
>>> output = pipe(conversation)Một số mô hình, chẳng hạn như Dia, cũng có thể được điều kiện để tạo ra các giao tiếp phi ngôn ngữ như cười, thở dài và khóc, hoặc thậm chí thêm nhạc. Dưới đây là một ví dụ như vậy:
>>> from transformers import pipeline
>>> pipe = pipeline("text-to-speech", model="nari-labs/Dia-1.6B-0626")
>>> text = "[S1] (clears throat) Hello! How are you? [S2] I'm good, thanks! How about you?"
>>> output = pipe(text)Lưu ý rằng Dia cũng chấp nhận các thẻ người nói như [S1] và [S2] để tạo ra một cuộc hội thoại giữa các giọng nói riêng biệt.
Để xem thêm các ví dụ về những gì CSM và các mô hình TTS được huấn luyện trước khác có thể làm, hãy tham khảo Khóa học Âm thanh của chúng tôi.
Nếu bạn đang tìm cách tinh chỉnh một mô hình TTS, các mô hình text-to-speech hiện có trong 🤗 Transformers là SpeechT5, FastSpeech2Conformer, Dia và CSM, mặc dù sẽ có thêm nhiều mô hình khác được bổ sung trong tương lai. SpeechT5 được huấn luyện trước trên một tổ hợp dữ liệu speech-to-text và text-to-speech, cho phép nó học một không gian thống nhất của các biểu diễn ẩn được chia sẻ bởi cả văn bản và giọng nói. Điều này có nghĩa là cùng một mô hình huấn luyện trước có thể được tinh chỉnh cho các tác vụ khác nhau. Hơn nữa, SpeechT5 hỗ trợ nhiều người nói thông qua x-vector speaker embeddings.
Phần còn lại của hướng dẫn này minh họa cách:
- Fine-tune SpeechT5 vốn được huấn luyện ban đầu trên giọng nói tiếng Anh, trên tập con ngôn ngữ Hà Lan (
nl) của bộ dữ liệu VoxPopuli. - Sử dụng mô hình đã tinh chỉnh của bạn để suy luận theo một trong hai cách: sử dụng pipeline hoặc trực tiếp.
Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt tất cả các thư viện cần thiết:
pip install transformers datasets soundfile torchcodec speechbrain accelerate
Cài đặt 🤗Transformers từ mã nguồn vì không phải tất cả các tính năng của SpeechT5 đều đã được hợp nhất vào một bản phát hành chính thức:
pip install git+https://github.com/huggingface/transformers.git
Để làm theo hướng dẫn này, bạn sẽ cần một GPU. Nếu bạn đang làm việc trong một notebook, hãy chạy dòng lệnh sau để kiểm tra xem có GPU khả dụng hay không:
!nvidia-smihoặc thay thế bằng cách dành cho GPU AMD:
!rocm-smi
Chúng tôi khuyến khích bạn đăng nhập vào tài khoản Hugging Face của mình để tải lên và chia sẻ mô hình của bạn với cộng đồng. Khi được yêu cầu, hãy nhập token của bạn để đăng nhập:
>>> from huggingface_hub import notebook_login
>>> notebook_login()Tải bộ dữ liệu
VoxPopuli là một tập dữ liệu giọng nói đa ngôn ngữ quy mô lớn, bao gồm dữ liệu được lấy từ các bản ghi sự kiện của Nghị viện Châu Âu trong giai đoạn 2009-2020. Tập dữ liệu này chứa dữ liệu audio-chuyển văn bản có nhãn cho 15 ngôn ngữ Châu Âu. Trong hướng dẫn này, chúng ta sẽ sử dụng tập con tiếng Hà Lan, bạn có thể tự do chọn một tập con khác.
Lưu ý rằng VoxPopuli hoặc bất kỳ bộ dữ liệu nhận dạng giọng nói tự động (ASR) nào khác có thể không phải là lựa chọn phù hợp nhất để huấn luyện các mô hình TTS. Những đặc điểm giúp ích cho ASR, chẳng hạn như tiếng ồn nền quá mức, thường là không mong muốn trong TTS. Tuy nhiên, việc tìm kiếm các bộ dữ liệu TTS chất lượng cao, đa ngôn ngữ và đa người nói có thể khá khó khăn.
Hãy tải dữ liệu:
>>> from datasets import load_dataset, Audio
>>> dataset = load_dataset("qmeeus/voxpopuli", "nl", split="train")
>>> len(dataset)
2096820968 ví dụ nên là đủ để fine-tuning. SpeechT5 yêu cầu dữ liệu âm thanh có tần số lấy mẫu là 16 kHz, vì vậy hãy đảm bảo các ví dụ trong dataset đáp ứng yêu cầu này:
dataset = dataset.cast_column("audio", Audio(sampling_rate=16000))Tiền xử lý dữ liệu
Hãy bắt đầu bằng cách xác định điểm kiểm tra (checkpoint) của mô hình cần sử dụng và nạp bộ xử lý (processor) phù hợp:
>>> from transformers import SpeechT5Processor
>>> checkpoint = "microsoft/speecht5_tts"
>>> processor = SpeechT5Processor.from_pretrained(checkpoint)Dọn dẹp văn bản cho tokenization của SpeechT5
Bắt đầu bằng cách làm sạch dữ liệu văn bản. Bạn sẽ cần phần tokenizer của processor để xử lý văn bản:
>>> tokenizer = processor.tokenizerCác ví dụ trong bộ dữ liệu chứa đặc trưng text với bản ghi âm. Lưu ý rằng bộ phân từ SpeechT5 không có bất kỳ token nào cho các con số, do đó mọi con số trong văn bản sẽ được chuyển đổi thành các token <unk>. Nếu bộ dữ liệu của bạn chứa các con số, hãy cân nhắc chuẩn hóa chúng sang dạng viết bằng chữ.
Vì SpeechT5 được huấn luyện trên ngôn ngữ tiếng Anh, nó có thể không nhận diện được một số ký tự trong bộ dữ liệu tiếng Hà Lan. Nếu
để nguyên như vậy, các ký tự này sẽ được chuyển đổi thành các token <unk>. Tuy nhiên, trong tiếng Hà Lan, một số ký tự như à được
dùng để nhấn âm tiết. Để bảo toàn ý nghĩa của văn bản, chúng ta có thể thay thế ký tự này bằng ký tự a thông thường.
Để xác định các token không được hỗ trợ, hãy trích xuất tất cả các ký tự duy nhất trong tập dữ liệu bằng SpeechT5Tokenizer, vốn hoạt động với các ký tự như là token. Để làm điều này, hãy viết hàm ánh xạ extract_all_chars để nối các bản chuyển tự từ tất cả các ví dụ thành một chuỗi và chuyển đổi nó thành một tập hợp các ký tự.
Hãy đảm bảo đặt batched=True và batch_size=-1 trong dataset.map() để tất cả các bản chuyển tự đều có sẵn cùng lúc cho hàm ánh xạ.
>>> def extract_all_chars(batch):
... all_text = " ".join(batch["text"])
... vocab = list(set(all_text))
... return {"vocab": [vocab], "all_text": [all_text]}
>>> vocabs = dataset.map(
... extract_all_chars,
... batched=True,
... batch_size=-1,
... keep_in_memory=True,
... remove_columns=dataset.column_names,
... )
>>> dataset_vocab = set(vocabs["vocab"][0])
>>> tokenizer_vocab = {k for k, _ in tokenizer.get_vocab().items()}Bây giờ bạn có hai tập hợp ký tự: một tập hợp chứa từ vựng từ bộ dữ liệu và một tập hợp chứa từ vựng từ tokenizer. Để xác định các ký tự không được hỗ trợ trong bộ dữ liệu, bạn có thể lấy hiệu giữa hai tập hợp này. Tập hợp kết quả sẽ chứa các ký tự có trong bộ dữ liệu nhưng không có trong tokenizer.
>>> dataset_vocab - tokenizer_vocab
{' ', 'à', 'ç', 'è', 'ë', 'í', 'ï', 'ö', 'ü'}Để xử lý các ký tự không được hỗ trợ đã xác định ở bước trước, hãy định nghĩa một hàm ánh xạ các ký tự này sang các token hợp lệ. Lưu ý rằng khoảng trắng đã được thay thế bằng ▁ trong tokenizer và không cần phải xử lý riêng.
>>> replacements = [
... ("à", "a"),
... ("ç", "c"),
... ("è", "e"),
... ("ë", "e"),
... ("í", "i"),
... ("ï", "i"),
... ("ö", "o"),
... ("ü", "u"),
... ]
>>> def cleanup_text(inputs):
... for src, dst in replacements:
... inputs["text"] = inputs["text"].replace(src, dst)
... return inputs
>>> dataset = dataset.map(cleanup_text)Giờ đây, khi bạn đã xử lý các ký tự đặc biệt trong văn bản, đã đến lúc chuyển trọng tâm sang dữ liệu âm thanh.
Diễn giả
Bộ dữ liệu VoxPopuli bao gồm giọng nói từ nhiều người nói, nhưng có bao nhiêu người nói được đại diện trong bộ dữ liệu? Để xác định điều này, chúng ta có thể đếm số lượng người nói duy nhất và số lượng ví dụ mà mỗi người nói đóng góp cho bộ dữ liệu. Với tổng cộng 20.968 ví dụ trong bộ dữ liệu, thông tin này sẽ giúp chúng ta hiểu rõ hơn về sự phân bố của người nói và ví dụ trong dữ liệu.
>>> from collections import defaultdict
>>> speaker_counts = defaultdict(int)
>>> for speaker_id in dataset["speaker_id"]:
... speaker_counts[speaker_id] += 1Bằng cách vẽ biểu đồ tần số (histogram), bạn có thể nắm được lượng dữ liệu có sẵn cho từng người nói.
>>> import matplotlib.pyplot as plt
>>> plt.figure()
>>> plt.hist(speaker_counts.values(), bins=20)
>>> plt.ylabel("Speakers")
>>> plt.xlabel("Examples")
>>> plt.show()
Biểu đồ tần số cho thấy khoảng một phần ba số người nói trong bộ dữ liệu có ít hơn 100 ví dụ, trong khi khoảng mười người nói có hơn 500 ví dụ. Để cải thiện hiệu quả huấn luyện và cân bằng bộ dữ liệu, chúng ta có thể giới hạn dữ liệu ở các người nói có từ 100 đến 400 ví dụ.
>>> def select_speaker(speaker_id):
... return 100 <= speaker_counts[speaker_id] <= 400
>>> dataset = dataset.filter(select_speaker, input_columns=["speaker_id"])Hãy kiểm tra xem còn bao nhiêu người nói:
>>> len(set(dataset["speaker_id"]))
42Hãy xem còn bao nhiêu ví dụ:
>>> len(dataset)
9973Bạn chỉ còn lại chưa đầy 10.000 ví dụ từ khoảng 40 người nói khác nhau, điều này nên là đủ.
Lưu ý rằng một số người nói có ít ví dụ có thể thực tế có nhiều âm thanh hơn nếu các ví dụ đó dài. Tuy nhiên, việc xác định tổng lượng âm thanh cho mỗi người nói đòi hỏi phải quét toàn bộ bộ dữ liệu, đây là một quá trình tốn thời gian, bao gồm việc tải và giải mã từng tệp âm thanh. Do đó, chúng tôi đã chọn bỏ qua bước này ở đây.
Nhúng giọng nói
Để cho phép mô hình TTS phân biệt giữa nhiều người nói, bạn cần tạo một speaker embedding cho mỗi ví dụ. Speaker embedding là một đầu vào bổ sung cho mô hình, nắm bắt các đặc điểm giọng nói của một người nói cụ thể. Để tạo các speaker embedding này, hãy sử dụng mô hình spkrec-xvect-voxceleb đã được huấn luyện trước từ SpeechBrain.
Tạo một hàm create_speaker_embedding() nhận vào một dạng sóng âm thanh đầu vào và xuất ra một vector 512 phần tử chứa embedding người nói tương ứng.
>>> import os
>>> import torch
>>> from speechbrain.inference.classifiers import EncoderClassifier
>>> from accelerate import Accelerator
>>> spk_model_name = "speechbrain/spkrec-xvect-voxceleb"
>>> device = Accelerator().device
>>> speaker_model = EncoderClassifier.from_hparams(
... source=spk_model_name,
... run_opts={"device": device},
... savedir=os.path.join("/tmp", spk_model_name),
... )
>>> def create_speaker_embedding(waveform):
... with torch.no_grad():
... speaker_embeddings = speaker_model.encode_batch(torch.tensor(waveform))
... speaker_embeddings = torch.nn.functional.normalize(speaker_embeddings, dim=2)
... speaker_embeddings = speaker_embeddings.squeeze().cpu().numpy()
... return speaker_embeddingsCần lưu ý rằng mô hình speechbrain/spkrec-xvect-voxceleb được huấn luyện trên giọng nói tiếng Anh từ bộ dữ liệu VoxCeleb, trong khi các ví dụ huấn luyện trong hướng dẫn này là bằng tiếng Hà Lan. Mặc dù chúng tôi tin rằng mô hình này vẫn sẽ tạo ra các embedding người nói hợp lý cho bộ dữ liệu tiếng Hà Lan của chúng tôi, nhưng giả định này có thể không đúng trong mọi trường hợp.
Để đạt kết quả tối ưu, chúng tôi khuyến nghị huấn luyện một mô hình X-vector trên giọng nói mục tiêu trước. Điều này sẽ đảm bảo rằng mô hình có khả năng nắm bắt tốt hơn các đặc điểm giọng nói đặc trưng có trong tiếng Hà Lan.
Xử lý bộ dữ liệu
Cuối cùng, hãy xử lý dữ liệu thành định dạng mà mô hình mong đợi. Tạo một hàm prepare_dataset nhận một ví dụ duy nhất và sử dụng đối tượng SpeechT5Processor để mã hóa văn bản đầu vào và nạp âm thanh đích vào dạng phổ log-mel. Hàm này cũng cần thêm các vector nhúng người nói như một đầu vào bổ sung.
>>> def prepare_dataset(example):
... audio = example["audio"]
... example = processor(
... text=example["text"],
... audio_target=audio["array"],
... sampling_rate=audio["sampling_rate"],
... return_attention_mask=False,
... )
... # strip off the batch dimension
... example["labels"] = example["labels"][0]
... # use SpeechBrain to obtain x-vector
... example["speaker_embeddings"] = create_speaker_embedding(audio["array"])
... return exampleKiểm tra việc xử lý có chính xác không bằng cách xem một ví dụ đơn lẻ:
>>> processed_example = prepare_dataset(dataset[0])
>>> list(processed_example.keys())
['input_ids', 'labels', 'stop_labels', 'speaker_embeddings']Embedding của người nói phải là một vector 512 phần tử:
>>> processed_example["speaker_embeddings"].shape
(512,)Các nhãn nên là một phổ log-mel với 80 bin mel.
>>> import matplotlib.pyplot as plt
>>> plt.figure()
>>> plt.imshow(processed_example["labels"].T)
>>> plt.show()
Lưu ý: Nếu bạn thấy phổ tần này gây khó hiểu, có thể do bạn quen với quy ước đặt tần số thấp ở phía dưới và tần số cao ở phía trên của biểu đồ. Tuy nhiên, khi vẽ phổ tần dưới dạng hình ảnh bằng thư viện matplotlib, trục y bị đảo ngược và phổ tần sẽ hiển thị ngược.
Bây giờ áp dụng hàm xử lý cho toàn bộ tập dữ liệu. Quá trình này sẽ mất từ 5 đến 10 phút.
>>> dataset = dataset.map(prepare_dataset, remove_columns=dataset.column_names)Bạn sẽ thấy một cảnh báo cho biết một số ví dụ trong tập dữ liệu dài hơn độ dài đầu vào tối đa mà mô hình có thể xử lý (600 token). Xóa các ví dụ đó khỏi tập dữ liệu. Ở đây chúng ta đi xa hơn nữa và để cho phép kích thước lô (batch size) lớn hơn, chúng ta sẽ xóa bất kỳ ví dụ nào dài hơn 200 token.
>>> def is_not_too_long(input_ids):
... input_length = len(input_ids)
... return input_length < 200
>>> dataset = dataset.filter(is_not_too_long, input_columns=["input_ids"])
>>> len(dataset)
8259Tiếp theo, tạo một phép chia train/test cơ bản:
>>> dataset = dataset.train_test_split(test_size=0.1)Trình tổng hợp dữ liệu
Để kết hợp nhiều ví dụ thành một batch, bạn cần định nghĩa một data collator tùy chỉnh. Collator này sẽ đệm các chuỗi ngắn hơn bằng các token padding, đảm bảo rằng tất cả các ví dụ có cùng độ dài. Đối với nhãn spectrogram, các phần được đệm sẽ được thay thế bằng giá trị đặc biệt -100. Giá trị đặc biệt này chỉ thị cho mô hình bỏ qua phần đó của spectrogram khi tính toán spectrogram loss.
>>> from dataclasses import dataclass
>>> from typing import Any, Dict, List, Union
>>> @dataclass
... class TTSDataCollatorWithPadding:
... processor: Any
... def __call__(self, features: list[dict[str, Union[list[int], torch.Tensor]]]) -> dict[str, torch.Tensor]:
... input_ids = [{"input_ids": feature["input_ids"]} for feature in features]
... label_features = [{"input_values": feature["labels"]} for feature in features]
... speaker_features = [feature["speaker_embeddings"] for feature in features]
... # collate the inputs and targets into a batch
... batch = processor.pad(input_ids=input_ids, labels=label_features, return_tensors="pt")
... # replace padding with -100 to ignore loss correctly
... batch["labels"] = batch["labels"].masked_fill(batch.decoder_attention_mask.unsqueeze(-1).ne(1), -100)
... # not used during fine-tuning
... del batch["decoder_attention_mask"]
... # round down target lengths to multiple of reduction factor
... if model.config.reduction_factor > 1:
... target_lengths = torch.tensor([len(feature["input_values"]) for feature in label_features])
... target_lengths = target_lengths.new(
... [length - length % model.config.reduction_factor for length in target_lengths]
... )
... max_length = max(target_lengths)
... batch["labels"] = batch["labels"][:, :max_length]
... # also add in the speaker embeddings
... batch["speaker_embeddings"] = torch.tensor(speaker_features)
... return batchTrong SpeechT5, đầu vào cho phần decoder của mô hình bị giảm đi một hệ số 2. Nói cách khác, nó loại bỏ mỗi bước thời gian xen kẽ trong chuỗi đích. Sau đó, decoder dự đoán một chuỗi có độ dài gấp đôi. Vì độ dài của chuỗi đích ban đầu có thể là số lẻ, data collator đảm bảo làm tròn xuống độ dài tối đa của batch để thành một bội số của 2.
>>> data_collator = TTSDataCollatorWithPadding(processor=processor)Huấn luyện mô hình
Tải mô hình đã được huấn luyện trước từ cùng checkpoint mà bạn đã dùng để tải processor:
>>> from transformers import SpeechT5ForTextToSpeech
>>> model = SpeechT5ForTextToSpeech.from_pretrained(checkpoint)Tùy chọn use_cache=True không tương thích với gradient checkpointing. Hãy tắt nó khi huấn luyện.
>>> model.config.use_cache = FalseĐịnh nghĩa các đối số huấn luyện. Ở đây, chúng ta không tính toán bất kỳ chỉ số đánh giá nào trong quá trình huấn luyện. Thay vào đó, chúng ta sẽ chỉ xem xét loss:
>>> from transformers import Seq2SeqTrainingArguments
>>> training_args = Seq2SeqTrainingArguments(
... output_dir="speecht5_finetuned_voxpopuli_nl", # change to a repo name of your choice
... per_device_train_batch_size=4,
... gradient_accumulation_steps=8,
... learning_rate=1e-5,
... warmup_steps=500,
... max_steps=4000,
... gradient_checkpointing=True,
... fp16=True,
... eval_strategy="steps",
... per_device_eval_batch_size=2,
... save_steps=1000,
... eval_steps=1000,
... logging_steps=25,
... report_to="trackio",
... load_best_model_at_end=True,
... greater_is_better=False,
... label_names=["labels"],
... push_to_hub=True,
... )Tạo đối tượng Trainer và truyền mô hình, tập dữ liệu và bộ sắp xếp dữ liệu vào đó.
>>> from transformers import Seq2SeqTrainer
>>> trainer = Seq2SeqTrainer(
... args=training_args,
... model=model,
... train_dataset=dataset["train"],
... eval_dataset=dataset["test"],
... data_collator=data_collator,
... processing_class=processor,
... )Và với đó, bạn đã sẵn sàng bắt đầu huấn luyện! Quá trình huấn luyện sẽ mất vài giờ. Tùy thuộc vào GPU của bạn,
có thể bạn sẽ gặp lỗi CUDA “out-of-memory” khi bắt đầu huấn luyện. Trong trường hợp này, bạn có thể giảm
per_device_train_batch_size dần dần theo các hệ số 2 và tăng gradient_accumulation_steps lên 2 lần để bù đắp.
>>> trainer.train()Để có thể sử dụng checkpoint của bạn với một pipeline, hãy đảm bảo lưu processor cùng với checkpoint:
>>> processor.save_pretrained("YOUR_ACCOUNT_NAME/speecht5_finetuned_voxpopuli_nl")Đẩy mô hình cuối cùng lên 🤗 Hub:
>>> trainer.push_to_hub()Suy luận
Suy luận bằng pipeline
Tuyệt, giờ bạn đã tinh chỉnh xong một mô hình, bạn có thể dùng nó để suy luận!
Trước tiên, hãy xem cách bạn có thể sử dụng nó với một pipeline tương ứng. Hãy tạo một pipeline "text-to-speech" với checkpoint của bạn:
>>> from transformers import pipeline
>>> pipe = pipeline("text-to-speech", model="YOUR_ACCOUNT_NAME/speecht5_finetuned_voxpopuli_nl")Chọn một đoạn văn bản bằng tiếng Hà Lan mà bạn muốn được đọc, ví dụ:
>>> text = "hallo allemaal, ik praat nederlands. groetjes aan iedereen!"Để sử dụng SpeechT5 với pipeline, bạn sẽ cần một speaker embedding. Hãy lấy nó từ một ví dụ trong bộ dữ liệu kiểm thử:
>>> example = dataset["test"][304]
>>> speaker_embeddings = torch.tensor(example["speaker_embeddings"]).unsqueeze(0)Bây giờ bạn có thể truyền text và speaker embeddings vào pipeline, và nó sẽ tự xử lý phần còn lại:
>>> forward_params = {"speaker_embeddings": speaker_embeddings}
>>> output = pipe(text, forward_params=forward_params)
>>> output
{'audio': array([-6.82714235e-05, -4.26525949e-04, 1.06134125e-04, ...,
-1.22392643e-03, -7.76011671e-04, 3.29112721e-04], dtype=float32),
'sampling_rate': 16000}Sau đó, bạn có thể nghe kết quả:
>>> from IPython.display import Audio
>>> Audio(output['audio'], rate=output['sampling_rate'])Chạy suy luận thủ công
Bạn có thể đạt được kết quả suy luận tương tự mà không cần sử dụng pipeline, tuy nhiên sẽ cần thêm nhiều bước hơn.
Tải mô hình từ 🤗 Hub:
>>> model = SpeechT5ForTextToSpeech.from_pretrained("YOUR_ACCOUNT/speecht5_finetuned_voxpopuli_nl")Chọn một ví dụ từ tập dữ liệu kiểm tra và lấy một vector nhúng người nói.
>>> example = dataset["test"][304]
>>> speaker_embeddings = torch.tensor(example["speaker_embeddings"]).unsqueeze(0)Định nghĩa văn bản đầu vào và thực hiện token hóa.
>>> text = "hallo allemaal, ik praat nederlands. groetjes aan iedereen!"
>>> inputs = processor(text=text, return_tensors="pt")Tạo một phổ âm (spectrogram) bằng mô hình của bạn:
>>> spectrogram = model.generate_speech(inputs["input_ids"], speaker_embeddings)Trực quan hóa phổ âm, nếu bạn muốn:
>>> plt.figure()
>>> plt.imshow(spectrogram.T)
>>> plt.show()
Cuối cùng, sử dụng vocoder để chuyển đổi spectrogram thành âm thanh.
>>> with torch.no_grad():
... speech = vocoder(spectrogram)
>>> from IPython.display import Audio
>>> Audio(speech.numpy(), rate=16000)Theo kinh nghiệm của chúng tôi, việc đạt được kết quả hài lòng từ mô hình này có thể khá khó khăn. Chất lượng của các embedding người nói dường như là một yếu tố quan trọng. Vì SpeechT5 được huấn luyện trước với các x-vector tiếng Anh, mô hình hoạt động tốt nhất khi sử dụng các embedding người nói tiếng Anh. Nếu giọng nói tổng hợp nghe kém, hãy thử sử dụng một embedding người nói khác.
Việc tăng thời lượng huấn luyện cũng có khả năng nâng cao chất lượng kết quả. Mặc dù vậy, giọng nói rõ ràng là tiếng Hà Lan thay vì tiếng Anh, và nó nắm bắt được các đặc điểm giọng nói của người nói (so sánh với âm thanh gốc trong ví dụ).
Một điều khác để thử nghiệm là cấu hình của mô hình. Ví dụ, hãy thử sử dụng config.reduction_factor = 1 để xem liệu điều này có cải thiện kết quả hay không.
Cuối cùng, việc xem xét các yếu tố đạo đức là rất cần thiết. Mặc dù công nghệ TTS có nhiều ứng dụng hữu ích, nhưng nó cũng có thể bị lạm dụng cho mục đích xấu, chẳng hạn như giả mạo giọng nói của một người mà không có sự biết đến hay đồng ý của họ. Vui lòng sử dụng TTS một cách thận trọng và có trách nhiệm.
Update on GitHub