首页
/ 使用 🤗 Transformers 微调 SpeechT5:从 VoxPopuli 荷兰语数据到自定义 TTS 语音合成

使用 🤗 Transformers 微调 SpeechT5:从 VoxPopuli 荷兰语数据到自定义 TTS 语音合成

2026-09-09 18:27:20作者:裘晴惠Vivianne

文本转语音(Text-to-Speech,TTS)是让机器把文字变成自然语音的核心任务,支持多语言、多说话人生成。本文以 🤗 Transformers 官方任务指南 docs/source/en/tasks/text-to-speech.md(及对应日文版 docs/source/ja/tasks/text-to-speech.md)为骨架,完整讲解两条主线:一是通过 text-to-speech 流水线开箱即用地合成语音;二是以 SpeechT5 为代表,从数据集加载、文本与音频预处理、说话人嵌入到训练与推理,端到端微调一个多说话人 TTS 模型。读完本文,你将掌握在 Transformers 中落地自定义 TTS 模型的完整实战方案。

TTS 任务与 🤗 Transformers 中的可用模型

TTS 的输入是文本,输出是可以直接播放的语音波形,且同一模型往往能生成多语言、多说话人的语音。在 🤗 Transformers 当前仓库中,可直接使用的 TTS 模型包括 BarkMMSVITSSpeechT5,以及较新加入的 Dia、CSM、FastSpeech2Conformer 等。其中部分模型还支持超出纯文本的生成能力,例如 Bark 可通过文本标记生成笑声、叹息、哭泣等非语言交流,甚至附带音乐;Dia 则支持 [S1][S2] 这类说话人标签来生成多人对话。

从微调角度看,目前仓库内可微调的 TTS 模型主要是 SpeechT5(以及 Dia、CSM、FastSpeech2Conformer 等)。SpeechT5 的特别之处在于它同时使用语音转文本(speech-to-text)与文本转语音(text-to-speech)两类数据进行预训练,从而学到文本与语音共享的统一隐表示空间——这意味着同一个预训练模型可以针对不同任务进行微调。此外,SpeechT5 通过 x-vector 说话人嵌入(speaker embeddings)支持多说话人生成,这也是本文微调流程的核心输入之一。

快速上手:text-to-speech 流水线

最简单的语音合成方式是利用 "text-to-audio" 流水线(其别名是 "text-to-speech")。流水线的实现位于 src/transformers/pipelines/text_to_audio.py 中的 TextToAudioPipeline,它支持任意 AutoModelForTextToWaveformAutoModelForTextToSpectrogram 模型。以 Bark 为例:

>>> from transformers import pipeline

>>> pipe = pipeline("text-to-speech", model="suno/bark-small")
>>> text = "[clears throat] This is a test ... and I just took a long pause."
>>> output = pipe(text)

在 Notebook 中可以用下面的代码直接收听结果:

>>> from IPython.display import Audio
>>> Audio(output["audio"], rate=output["sampling_rate"])

output 是一个包含 audio(波形数组)与 sampling_rate(采样率)字段的字典。从源码可见,TextToAudioPipelinemodel_type == "speecht5" 的模型会自动加载默认的 HiFi-GAN 声码器(SpeechT5HifiGan)并将采样率设为声码器的采样率(16 kHz);对 Bark 这类需要语义长度的模型,则会在预处理阶段使用 generation_config 中的 max_input_semantic_length(默认 256)来约束输入。

微调 SpeechT5:环境准备与数据加载

本文的微调目标是:把原本在英语语音上训练的 SpeechT5 检查点 microsoft/speecht5_tts,在 VoxPopuli 数据集的荷兰语(nl)子集上微调,得到能说荷兰语的多说话人 TTS 模型。

安装依赖与检查 GPU

首先确保以下库已安装:

pip install datasets soundfile speechbrain accelerate

注意:英文版指南还推荐安装 librosatorchcodec 等音频加载库,可根据实际环境按需补充。

由于 SpeechT5 的部分 TTS 特性尚未全部合并进正式发布版,指南建议从源码安装 Transformers:

pip install git+https://github.com/huggingface/transformers.git

微调需要 GPU。在 Notebook 中可通过以下命令确认 GPU 可用(AMD GPU 则用 !rocm-smi):

!nvidia-smi

建议先登录 Hugging Face 账号,便于训练后把模型上传分享:

>>> from huggingface_hub import notebook_login

>>> notebook_login()

加载 VoxPopuli 数据集

VoxPopuli 是一个大规模多语言语音语料库,数据源自 2009–2020 年欧洲议会的会议录音,包含 15 种欧洲语言的带标注语音-转写数据。本指南使用荷兰语子集,你也可以自由换成其他子集:

>>> from datasets import load_dataset, Audio

>>> dataset = load_dataset("facebook/voxpopuli", "nl", split="train")
>>> len(dataset)
20968

20968 条样本对微调已经足够。需要说明的是,VoxPopuli 这类自动语音识别(ASR)数据集并非 TTS 训练的理想选择——对 ASR 有利的特性(如过多背景噪声)通常对 TTS 反而有害;但高质量、多语言、多说话人的 TTS 数据集往往很难获得,因此这里用它做演示。

SpeechT5 期望音频采样率为 16 kHz,因此需要把数据集中的音频列强制转换为该采样率:

dataset = dataset.cast_column("audio", Audio(sampling_rate=16000))

从源码看,SpeechT5 的 feature_extraction_speecht5.py 中默认 sampling_rate=16000num_mel_bins=80,模型配置 configuration_speecht5.py 同样以 80 个 mel bin、16 kHz 为默认前提,二者必须保持一致。

数据预处理

预处理阶段的核心任务是把原始文本与音频整理成模型能消费的 input_idslabels(log-mel 频谱)、stop_labelsspeaker_embeddings

先定义检查点并加载对应的处理器(Processor 由分词器 + 特征提取器组合而成):

>>> from transformers import SpeechT5Processor

>>> checkpoint = "microsoft/speecht5_tts"
>>> processor = SpeechT5Processor.from_pretrained(checkpoint)

文本清理:字符级词汇检查与替换

处理文本需要用到处理器的分词器部分:

>>> tokenizer = processor.tokenizer

数字规范化:注意 SpeechT5 分词器没有数字 token,文本中的数字会被转成 <unk>。因此如果数据集含数字,应先将数字规范化为书写形式。仓库中 tokenization_speecht5.py 内置了 normalizer 属性,且附带 number_normalizer.py 实现了数字拼写转换(spell_number / convert),可在分词时启用 normalize=True 来自动处理。

特殊字符:SpeechT5 在英语上训练,可能不认识荷兰语中的某些字符(如 à 这类用于音节重读的字符),若不做处理会被转成 <unk>。为了保留文本语义,可以把它们替换为对应的普通字母。

先用 SpeechT5Tokenizer(以字符为 token)提取数据集中所有唯一字符。写一个 extract_all_chars 映射函数,把所有转写拼接成一个字符串并转为字符集合;注意 dataset.map() 中必须设置 batched=Truebatch_size=-1,才能让映射函数一次性看到全部转写:

>>> def extract_all_chars(batch):
...     all_text = " ".join(batch["normalized_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()}

现在有了两个字符集合:数据集词汇与分词器词汇。两者做差集即可找出数据集中存在但分词器不支持的字符:

>>> dataset_vocab - tokenizer_vocab
{' ', 'à', 'ç', 'è', 'ë', 'í', 'ï', 'ö', 'ü'}

对识别出的不支持字符,定义一个替换映射到有效 token。注意空格在分词器中已被替换为 ,无需单独处理:

>>> replacements = [
...     ("à", "a"),
...     ("ç", "c"),
...     ("è", "e"),
...     ("ë", "e"),
...     ("í", "i"),
...     ("ï", "i"),
...     ("ö", "o"),
...     ("ü", "u"),
... ]


>>> def cleanup_text(inputs):
...     for src, dst in replacements:
...         inputs["normalized_text"] = inputs["normalized_text"].replace(src, dst)
...     return inputs


>>> dataset = dataset.map(cleanup_text)

说话人分析:统计分布与过滤

VoxPopuli 包含多位说话人。为了解数据分布,先统计每个说话人贡献的样本数:

>>> from collections import defaultdict

>>> speaker_counts = defaultdict(int)

>>> for speaker_id in dataset["speaker_id"]:
...     speaker_counts[speaker_id] += 1

绘制直方图可直观看出各说话人的数据量:

>>> import matplotlib.pyplot as plt

>>> plt.figure()
>>> plt.hist(speaker_counts.values(), bins=20)
>>> plt.ylabel("Speakers")
>>> plt.xlabel("Examples")
>>> plt.show()

从直方图可以看出:约三分之一的说话人样本不足 100 条,而约 10 位说话人拥有超过 500 条样本。为提高训练效率并平衡数据集,把数据限制在每位说话人 100~400 条样本:

>>> def select_speaker(speaker_id):
...     return 100 <= speaker_counts[speaker_id] <= 400


>>> dataset = dataset.filter(select_speaker, input_columns=["speaker_id"])

过滤后剩余说话人数量与样本数:

>>> len(set(dataset["speaker_id"]))
42

>>> len(dataset)
9973

约 40 位独特说话人、近一万条样本,对微调而言已经足够。需要说明的是,样本少但单条长的说话人实际可用的音频总量可能更多,但统计这一信息需要扫描并解码整个数据集,耗时较长,本指南选择跳过。

说话人嵌入:用 SpeechBrain 提取 x-vector

要让 TTS 模型区分不同说话人,需要为每条样本生成一个说话人嵌入——它是模型的一个额外输入,用于捕捉特定说话人的音色特征。这里使用 SpeechBrain 预训练的 spkrec-xvect-voxceleb 模型。

写一个 create_speaker_embedding() 函数:输入音频波形,输出 512 维向量:

>>> import os
>>> import torch
>>> from speechbrain.pretrained import EncoderClassifier

>>> spk_model_name = "speechbrain/spkrec-xvect-voxceleb"

>>> device = "cuda" if torch.cuda.is_available() else "cpu"
>>> 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_embeddings

需要注意:spkrec-xvect-voxceleb 是在 VoxCeleb 英语语音上训练的,而本指南的训练数据是荷兰语。通常它仍能为荷兰语数据生成合理的说话人嵌入,但这个假设并非在所有情况下都成立。为获得最佳效果,建议先在目标语音上训练一个 x-vector 模型,使其更好地捕捉荷兰语中独特的语音特征。

从模型侧印证:SpeechT5Configspeaker_embedding_dim 默认值为 512(见 configuration_speecht5.py),与 x-vector 输出维度一致;模型 forward 接收的 speaker_embeddings 形状即为 (batch_size, config.speaker_embedding_dim)

处理数据集:生成标签与嵌入

最后把数据整理成模型期望的格式。prepare_dataset 函数处理单条样本:用 SpeechT5Processor 对输入文本做 tokenize,并把目标音频加载成 log-mel 频谱;同时额外加入说话人嵌入:

>>> def prepare_dataset(example):
...     audio = example["audio"]

...     example = processor(
...         text=example["normalized_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 example

用单条样本验证处理结果:

>>> processed_example = prepare_dataset(dataset[0])
>>> list(processed_example.keys())
['input_ids', 'labels', 'stop_labels', 'speaker_embeddings']

说话人嵌入应是 512 维向量:

>>> processed_example["speaker_embeddings"].shape
(512,)

labels 则是包含 80 个 mel bin 的 log-mel 频谱,可可视化确认:

>>> import matplotlib.pyplot as plt

>>> plt.figure()
>>> plt.imshow(processed_example["labels"].T)
>>> plt.show()

小提示:如果你觉得这张频谱图"上下颠倒",是因为 matplotlib 把 y 轴翻转了(图像坐标系中 y 轴向下增长),并非数据出错。这与习惯上"低频在下、高频在上"的绘图约定相反。

把处理函数应用到整个数据集(约需 5~10 分钟):

>>> dataset = dataset.map(prepare_dataset, remove_columns=dataset.column_names)

过程中会出现警告:部分样本超过模型能处理的最大输入长度(600 token)。将这些样本删除;这里更进一步,为了允许更大的 batch size,把超过 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)
8259

最后做基本的训练/测试划分:

>>> dataset = dataset.train_test_split(test_size=0.1)

自定义数据整理器:TTSDataCollatorWithPadding

要把多条样本合成一个 batch,需要自定义数据整理器。它将较短的序列用 padding token 补齐到相同长度;对于频谱标签,padding 部分替换为特殊值 -100,该值会在计算频谱损失时告诉模型忽略对应区域(这一点与模型 forward 中"labels 中被设为 -100.0 的时间步在损失计算时被忽略"的约定完全一致):

>>> 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 batch

关于 reduction_factor:SpeechT5 的 decoder 输入会被缩减 2 倍,即丢弃目标序列中每隔一个的时间步,decoder 随后预测长度两倍的序列。由于原始目标序列长度可能为奇数,数据整理器需要把 batch 的最大长度向下取整为 2 的倍数。该缩减因子对应 configuration_speecht5.py 中的 reduction_factor(默认 2),在推理调优时也可以把它改成 1 来观察效果。

实例化数据整理器:

>>> data_collator = TTSDataCollatorWithPadding(processor=processor)

训练模型

从与加载处理器相同的检查点加载预训练模型:

>>> from transformers import SpeechT5ForTextToSpeech

>>> model = SpeechT5ForTextToSpeech.from_pretrained(checkpoint)

use_cache=True 与梯度检查点不兼容,训练前需关闭:

>>> model.config.use_cache = False

modeling_speecht5.py 的源码可见,SpeechT5ForTextToSpeech 由文本预网编码器(SpeechT5EncoderWithTextPrenet)、语音预网解码器(SpeechT5DecoderWithSpeechPrenet)和语音解码器 postnet(SpeechT5SpeechDecoderPostnet)构成;训练时若提供 labels,会通过 shift_spectrograms_right 对频谱右移,并由 SpeechT5SpectrogramLoss 计算损失(包括 use_guided_attention_loss 引导注意力损失,默认开启)。

训练参数详解

定义训练参数。这里在训练过程中不计算评估指标,只观察 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=["tensorboard"],
...     load_best_model_at_end=True,
...     greater_is_better=False,
...     label_names=["labels"],
...     push_to_hub=True,
... )

各关键参数的作用:

  • output_dir:checkpoint 输出目录,建议改为自己命名的仓库名;
  • per_device_train_batch_size=4gradient_accumulation_steps=8:等效 batch size 为 4×8=32,两者可按显存情况联动调整;
  • learning_rate=1e-5:微调建议用较小学习率;
  • max_steps=4000:以步数而非 epoch 控制训练总量;
  • gradient_checkpointing=True:以计算换显存,是 SpeechT5 这类 seq2seq 模型可训练的关键(也因此必须关闭 use_cache);
  • fp16=True:混合精度训练,进一步节省显存;
  • eval_strategy="steps"eval_steps=1000:每隔 1000 步评估一次;
  • load_best_model_at_end=True 配合 greater_is_better=False:按最小 loss 挑选最佳 checkpoint;
  • label_names=["labels"]:告诉 Trainer 频谱标签字段名,避免与 Seq2SeqLM 的默认 labels 语义混淆;
  • push_to_hub=True:训练结束后把模型推送到 Hub。

实例化 Seq2SeqTrainer,传入模型、数据集与数据整理器:

>>> 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,
... )

启动训练与显存调优

>>> trainer.train()

训练耗时数小时。若在启动时遇到 CUDA "out of memory" 错误,可将 per_device_train_batch_size 按 2 的倍数逐步减小,同时把 gradient_accumulation_steps 翻倍来补偿等效 batch size。

要让 checkpoint 能被流水线使用,务必把 processor 与 checkpoint 一起保存:

>>> processor.save_pretrained("YOUR_ACCOUNT_NAME/speecht5_finetuned_voxpopuli_nl")

最后把最终模型推送到 Hub:

>>> trainer.push_to_hub()

推理

方式一:使用 pipeline

微调完成后即可用于推理。先用 "text-to-speech" 流水线加载自己的 checkpoint:

>>> from transformers import pipeline

>>> pipe = pipeline("text-to-speech", model="YOUR_ACCOUNT_NAME/speecht5_finetuned_voxpopuli_nl")

选择一段希望朗读的荷兰语文本,例如:

>>> text = "hallo allemaal, ik praat nederlands. groetjes aan iedereen!"

通过流水线使用 SpeechT5 需要说话人嵌入,可从测试集某条样本取得:

>>> example = dataset["test"][304]
>>> speaker_embeddings = torch.tensor(example["speaker_embeddings"]).unsqueeze(0)

把文本与说话人嵌入一起传给流水线,其余交给它处理:

>>> 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}

收听结果:

>>> from IPython.display import Audio
>>> Audio(output['audio'], rate=output['sampling_rate'])

这里 forward_params 会被透传给模型 forward/generate,对应 text_to_audio.py_forward 对额外张量参数的设备对齐处理;对于 SpeechT5 这类频谱模型,流水线还会自动加载 HiFi-GAN 声码器把频谱转成波形,并保证 sampling_rate 与声码器一致(16 kHz)。

方式二:手动推理

不经过流水线也能得到相同结果,只是步骤更多。从 Hub 加载模型:

>>> model = SpeechT5ForTextToSpeech.from_pretrained("YOUR_ACCOUNT/speecht5_finetuned_voxpopuli_nl")

从测试集取一条样本获得说话人嵌入:

>>> example = dataset["test"][304]
>>> speaker_embeddings = torch.tensor(example["speaker_embeddings"]).unsqueeze(0)

定义输入文本并分词:

>>> text = "hallo allemaal, ik praat nederlands. groetjes aan iedereen!"
>>> inputs = processor(text=text, return_tensors="pt")

用模型生成频谱:

>>> spectrogram = model.generate_speech(inputs["input_ids"], speaker_embeddings)

如需可视化频谱:

>>> plt.figure()
>>> plt.imshow(spectrogram.T)
>>> plt.show()

最后用声码器把频谱转成声音:

>>> with torch.no_grad():
...     speech = vocoder(spectrogram)

>>> from IPython.display import Audio

>>> Audio(speech.numpy(), rate=16000)

其中 generate_speechSpeechT5ForTextToSpeech 的核心推理接口(见 modeling_speecht5.py),底层调用 _generate_speech。其关键参数包括:

  • threshold=0.5:当预测的停止 token 概率超过该值时结束生成;
  • minlenratio=0.0 / maxlenratio=20.0:用于计算输出序列的最小/最大允许长度;
  • vocoder=None:若提供声码器则直接输出波形,否则输出 log-mel 频谱;
  • output_cross_attentionsreturn_output_lengths:分别控制是否返回解码器交叉注意力与具体长度。

结果调优与注意事项

根据官方指南的实践经验,从该模型获得满意结果可能有一定挑战:

  • 说话人嵌入质量是关键因素:SpeechT5 使用英语 x-vector 预训练,因此在英语说话人嵌入上表现最佳。若合成语音质量差,可尝试换用不同的说话人嵌入。
  • 延长训练时长:通常能进一步提升音质。即便使用较短训练,荷兰语口音仍清晰可辨,并能捕捉示例中原说话人的音色特征。
  • 调整模型配置:例如尝试 config.reduction_factor = 1,观察是否改善结果。

伦理考虑

最后必须强调伦理问题。TTS 技术有大量正当用途,但也可能被用于恶意目的,例如在他人不知情或未同意的情况下伪造其声音。请审慎且负责任地使用 TTS。

延伸阅读

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395