簡述
github地址在
GitHub - xinchen-ai/Westlake-OmniContribute to xinchen-ai/Westlake-Omni development by creating an account on GitHub.https://github.com/xinchen-ai/Westlake-Omni
Westlake-Omni 是由西湖心辰(xinchen-ai)開發的一個開源中文情感端到端語音交互大模型,托管在 Hugging Face 平臺 , Hugging Face地址
https://huggingface.co/xinchen-ai/Westlake-Omnihttps://huggingface.co/xinchen-ai/Westlake-Omni它旨在通過統一的文本和語音模態處理,實現低延遲、高質量的中文情感語音交互。該模型亮點是
?Trained on a high-quality Chinese emotional speech dataset, enabling native emotional speech interaction in Chinese.? 在高質量的中文情感語音數據集上訓練,使其能夠實現原生的中文情感語音交互。?
應用場景
- 智能助手:在手機或智能家居設備中提供情感化的語音交互。
- 客戶服務:作為自動客服,處理咨詢和投訴,提供 24/7 服務。
- 教育輔助:支持語言學習和課程輔導,生成情感化的教學語音。
- 醫療咨詢:提供語音交互的健康指導,增強患者體驗。
- 娛樂與新聞:生成情感化的游戲對話或新聞播報。
1 Westlake-Omni 模型概述
Westlake-Omni 是一個多模態大語言模型,專注于中文情感語音交互。其核心特點包括:
- 統一模態處理:通過離散表示法(discrete representations),將語音和文本模態統一處理,簡化跨模態交互。
- 低延遲交互:支持實時語音輸入和輸出,生成文本和語音響應幾乎無延遲。
- 情感表達:在高質量中文情感語音數據集上訓練,能夠理解和生成具有情感色彩的語音,增強交互的人性化。
- 開源特性:模型代碼和權重在 GitHub(https://github.com/xinchen-ai/Westlake-Omni)和 Hugging Face 上公開,支持社區進一步開發和優化。
2. 模型原理與架構
Westlake-Omni 的核心在于其多模態架構,能夠同時處理語音和文本輸入,并生成相應的文本和情感語音輸出。以下從原理和架構層面逐步講解。
2.1 統一模態處理:離散表示法
Westlake-Omni 采用離散表示法(discrete representations)來統一文本和語音模態的處理。傳統多模態模型通常需要獨立的語音識別(ASR)、文本處理(NLP)和語音合成(TTS)模塊,而 Westlake-Omni 通過將語音和文本轉化為統一的離散 token 表示,簡化了模態間的轉換和處理流程。
- 離散表示的原理:
- 語音信號(如 WAV 文件)通過編碼器(可能是 Whisper 或 Wave2Vec 類似的預訓練模型)轉換為離散的語音 token。
- 文本輸入直接通過分詞器(tokenizer)轉換為文本 token。
- 這些 token 在模型內部被統一編碼為嵌入向量(embeddings),進入相同的 transformer 架構處理。
- 輸出端,模型可以生成文本 token 或語音 token,并通過解碼器轉換為自然語言或語音。
- 優勢:
- 統一表示減少了模態轉換的復雜性,提高了計算效率。
- 支持端到端的訓練和推理,降低延遲。
- 便于擴展到其他模態。
2.2 模型架構
Westlake-Omni 的架構可以分為以下幾個關鍵組件(以下為文字描述的結構,建議參考 GitHub 倉庫中的架構圖):
- 輸入編碼器:
- 語音編碼器:將原始音頻(例如 WAV 文件)編碼為離散 token,可能基于 Whisper 或類似的語音預訓練模型。
- 文本分詞器:將輸入文本(例如“最近心情不好,能聊聊嗎?”)分詞為 token,生成嵌入向量。
- 統一嵌入層:將語音和文本 token 映射到一個共享的嵌入空間,形成統一的輸入表示。
- Transformer 核心:
- 基于 Transformer 的多層架構,包含自注意力(self-attention)和前饋神經網絡(FFN)。
- 支持多模態輸入的上下文建模,能夠捕捉語音中的情感線索和文本中的語義信息。
- 可能采用因果注意力(causal attention)機制,確保實時生成(即生成當前 token 時不依賴未來 token)。
- 情感建模模塊:
- 專門設計的情感理解和生成模塊,用于分析語音輸入中的情感色彩(如語調、語速)并在輸出中注入相應的情感。
- 可能通過額外的注意力機制或嵌入層,在生成語音時控制情感表達(如高興、悲傷、平靜)。
- 輸出解碼器:
- 文本解碼器:將 Transformer 的輸出 token 轉換為自然語言文本。
- 語音解碼器:將 token 轉換為語音波形,可能基于預訓練的 TTS 模型(如 Tacotron 或 VITS)。
- 支持同時生成文本和語音,實現“邊思考邊說話”的效果。
- 低延遲優化:
- 采用流式處理(streaming processing),將輸入音頻分塊(chunked input)處理,減少初始延遲。
- 輸出端通過增量生成(incremental generation),實時產生語音和文本。
2.3 模型代碼
FireflyArchitecture 模型
FireflyArchitecture 是一個專門為音頻處理設計的神經網絡模型,主要用于將輸入音頻(如語音)轉換為高質量的音頻輸出,典型應用包括文本轉語音(TTS)或語音轉換。它的工作流程可以概括為以下幾個步驟:
- 音頻預處理:將原始音頻波形轉換為梅爾頻譜圖(Mel-Spectrogram),這是一種模仿人類聽覺的頻率表示形式。
- 特征編碼:將梅爾頻譜圖編碼為高層次的特征表示(latent representation)。
- 特征量化:通過量化和下采樣,將特征壓縮為離散的 token 表示,減少數據量并便于處理。
- 音頻生成:將量化的特征解碼為高質量的音頻波形。
模型由以下四個核心組件組成:
- LogMelSpectrogram:將原始音頻轉換為梅爾頻譜圖。
- ConvNeXtEncoder:對梅爾頻譜圖進行編碼,提取高層次特征。
- DownsampleFiniteScalarQuantize:對特征進行量化和下采樣,生成離散表示。
- HiFiGANGenerator:將量化后的特征解碼為音頻波形。
1. LogMelSpectrogram(梅爾頻譜圖轉換)
作用:將原始音頻波形(時域信號)轉換為梅爾頻譜圖,這是一種基于頻率的表示形式,更適合人類聽覺感知和后續處理。
通俗解釋:
- 想象音頻波形是一條上下波動的曲線,記錄了聲音的振幅隨時間變化。直接處理這種波形很復雜,因為它包含大量數據。
- LogMelSpectrogram 就像一個“音頻分析儀”,它把波形分解成不同頻率的成分(類似樂譜中的音高),然后按照人類耳朵對頻率的敏感度(梅爾尺度)重新組織這些信息。
- 最終輸出的是一個二維圖像(梅爾頻譜圖),橫軸是時間,縱軸是頻率,亮度表示強度。
實現細節:
- 輸入:原始音頻波形(1D 張量,形狀為 [batch_size, 1, time_steps])。
- 處理步驟:
- 短時傅里葉變換(STFT):通過 torch.stft 將音頻分成小段(幀),計算每段的頻率成分,生成線性頻譜圖。
- 參數:n_fft=2048(傅里葉變換點數)、win_length=2048(窗口長度)、hop_length=512(幀間步長)。
- 使用漢寧窗(Hann Window)平滑信號,減少頻譜泄漏。
- 梅爾尺度轉換:通過梅爾濾波器組(torchaudio.functional.melscale_fbanks)將線性頻譜圖轉換為梅爾頻譜圖。
- 參數:n_mels=160(梅爾濾波器數量)、sample_rate=44100(采樣率)、f_min=0.0(最低頻率)、f_max=22050(最高頻率)。
- 對數壓縮:對梅爾頻譜圖應用對數操作(torch.log),將幅度壓縮到更適合神經網絡處理的范圍。
- 短時傅里葉變換(STFT):通過 torch.stft 將音頻分成小段(幀),計算每段的頻率成分,生成線性頻譜圖。
- 輸出:梅爾頻譜圖(形狀為 [batch_size, n_mels, time_frames]),其中 time_frames = time_steps // hop_length。
- 關鍵特性:
- 支持動態采樣率調整(通過重采樣)。
- 可選擇返回線性頻譜圖(return_linear=True)用于調試或多任務訓練。
- 使用反射填充(reflect 模式)處理音頻邊界,避免邊緣失真。
def forward(self, x: Tensor, return_linear: bool = False, sample_rate: int = None) -> Tensor:if sample_rate is not None and sample_rate != self.sample_rate:x = F.resample(x, orig_freq=sample_rate, new_freq=self.sample_rate)linear = self.spectrogram(x) # 線性頻譜圖x = self.apply_mel_scale(linear) # 梅爾頻譜圖x = self.compress(x) # 對數壓縮if return_linear:return x, self.compress(linear)return x
- 梅爾頻譜圖比原始波形更緊湊,減少了數據量,便于神經網絡處理。
- 梅爾尺度模擬了人類聽覺對高低頻的非線性感知,使得模型更擅長處理語音相關任務。
2. ConvNeXtEncoder(特征編碼器)
作用:對梅爾頻譜圖進行編碼,提取高層次的特征表示,用于后續量化和解碼。
通俗解釋:
- 梅爾頻譜圖就像一張描述聲音的“圖像”,但它仍然包含很多冗余信息。ConvNeXtEncoder 就像一個“特征提取器”,它分析這張圖像,提煉出最重要的模式和結構(比如語音的音調、節奏、語義)。
- 它使用了一種現代化的卷積網絡結構(ConvNeXt),通過多層處理逐步將梅爾頻譜圖壓縮為更抽象的特征表示。
實現細節:
- 輸入:梅爾頻譜圖(形狀為 [batch_size, n_mels=160, time_frames])。
- 結構:
- 下采樣層(downsample_layers):
- 初始層(stem):通過 FishConvNet(1D 卷積)將輸入通道從 n_mels=160 轉換為第一個維度 dims[0]=128,并應用層歸一化(LayerNorm)。
- 后續下采樣層:通過 1x1 卷積和層歸一化,將通道數逐步增加(dims=[128, 256, 384, 512]),壓縮時間維度。
- 階段(stages):
- 包含多個 ConvNeXtBlock,每個塊是一個殘差結構,結合深度卷積(depthwise conv)、層歸一化、MLP(多層感知機)和隨機 DropPath(隨機深度,增強泛化能力)。
- 每個階段有不同數量的塊(depths=[3, 3, 9, 3]),對應不同的通道數(dims)。
- 歸一化:最后通過層歸一化(LayerNorm)穩定輸出。
- 下采樣層(downsample_layers):
- 輸出:高層次特征表示(形狀為 [batch_size, dims[-1]=512, reduced_time_frames]),時間維度因下采樣而減少。
- 關鍵特性:
- 使用 ConvNeXtBlock,結合深度卷積和 MLP,提升特征提取能力。
- 支持隨機深度(drop_path_rate=0.2),防止過擬合。
- 初始化權重采用截斷正態分布(trunc_normal_),確保訓練穩定性。
def forward(self, x: torch.Tensor) -> torch.Tensor:for i in range(len(self.downsample_layers)):x = self.downsample_layers[i](x)x = self.stages[i](x)return self.norm(x)
- ConvNeXtEncoder 提取了音頻的語義和結構信息,為后續量化提供了高質量的特征。
- 其現代化的卷積設計(ConvNeXt)比傳統卷積網絡更高效,適合處理復雜音頻數據。
3. DownsampleFiniteScalarQuantize(特征量化和下采樣)
作用:將編碼后的特征量化為離散的 token 表示,并通過下采樣減少時間維度,壓縮數據量。
通俗解釋:
- 編碼后的特征就像一本厚厚的書,包含很多細節,但我們只需要一個簡短的“摘要”。DownsampleFiniteScalarQuantize 就像一個“壓縮機”,它把特征簡化為一組數字(token),就像把一首歌壓縮成幾個關鍵音符。
- 它還通過下采樣減少時間分辨率,降低計算量。
實現細節:
- 輸入:編碼后的特征(形狀為 [batch_size, dim=512, time_frames])。
- 結構:
- 下采樣(downsample):
- 通過一系列 FishConvNet 和 ConvNeXtBlock,將時間維度按 downsample_factor=[2, 2] 縮減(總縮減因子為 4)。
- 通道數根據 downsample_dims 調整,保持信息完整性。
- 量化(residual_fsq):
- 使用 GroupedResidualFSQ(分組殘差有限標量量化),將特征量化為離散的索引(indices)。
- 參數:n_codebooks=1(量化器數量)、n_groups=8(分組數)、levels=[8, 5, 5, 5](量化級別,約 2^10 個可能值)。
- 上采樣(upsample):
- 在解碼時,通過 FishTransConvNet 和 ConvNeXtBlock,將量化后的特征恢復到原始時間分辨率。
- 下采樣(downsample):
- 輸出:
- 編碼:量化索引(形狀為 [batch_size, n_groups * n_codebooks, reduced_time_frames])。
- 解碼:恢復的特征(形狀為 [batch_size, dim=512, original_time_frames])。
- 關鍵特性:
- 向量量化(FSQ)減少了存儲和計算需求,適合實時應用。
- 分組殘差量化提高了量化精度。
- 下采樣和上采樣確保時間維度的可逆性。
def encode(self, z):z = self.downsample(z)_, indices = self.residual_fsq(z.mT)indices = rearrange(indices, "g b l r -> b (g r) l")return indicesdef decode(self, indices: torch.Tensor):indices = rearrange(indices, "b (g r) l -> g b l r", g=self.residual_fsq.groups)z_q = self.residual_fsq.get_output_from_indices(indices)z_q = self.upsample(z_q.mT)return z_q
4. HiFiGANGenerator(音頻生成器)
作用:將量化后的特征解碼為高質量的音頻波形。
通俗解釋:
- 量化后的特征就像一個簡化的“樂譜”,HiFiGANGenerator 是一個“音樂家”,它根據這個樂譜重新演奏出一首完整的歌曲(音頻波形)。
- 它使用了一種高效的生成器結構(HiFi-GAN),通過上采樣和殘差塊生成逼真的音頻。
實現細節:
- 輸入:量化后恢復的特征(形狀為 [batch_size, dim=512, time_frames])。
- 結構:
- 預卷積(conv_pre):
- 通過 FishConvNet 將輸入通道從 num_mels=512 轉換為初始通道 upsample_initial_channel=512。
- 上采樣層(ups):
- 通過 FishTransConvNet,將時間維度按 upsample_rates=[8, 8, 2, 2, 2] 上采樣(總因子為 512,匹配 hop_length)。
- 通道數逐步減半(512 → 256 → 128 → 64 → 32)。
- 殘差塊(resblocks):
- 使用 ParallelBlock,包含多個 ResBlock1,每個塊有不同核大小(resblock_kernel_sizes=[3, 7, 11])和膨脹率(resblock_dilation_sizes)。
- 并行處理不同核大小的特征,增強多樣性。
- 后處理:
- 通過 SiLU 激活(activation_post)和 FishConvNet(conv_post)生成最終波形。
- 使用 tanh 激活將輸出限制在 [-1, 1],匹配音頻波形范圍。
- 預卷積(conv_pre):
- 輸出:音頻波形(形狀為 [batch_size, 1, time_steps]),時間步數為 time_frames * hop_length。
- 關鍵特性:
- HiFi-GAN 結構以高保真音頻生成著稱,廣泛用于 TTS。
- 權重歸一化(weight_norm)提高訓練穩定性。
- 支持梯度檢查點(checkpoint),降低內存占用。
def forward(self, x):x = self.conv_pre(x)for i in range(self.num_upsamples):x = F.silu(x, inplace=True)x = self.ups[i](x)x = self.resblocks[i](x)x = self.activation_post(x)x = self.conv_post(x)x = torch.tanh(x)return x
- HiFiGANGenerator 確保生成的音頻具有高保真度,接近人類語音。
- 其上采樣和殘差設計平衡了質量和效率,適合實時應用。
3 結構示意圖
Westlake-Omni 的低延遲特性是其一大亮點,依賴以下技術:
- 流式輸入處理:語音輸入被分塊處理,每收到一小段音頻即可開始編碼和生成響應,無需等待完整輸入。
- 增量生成:模型在生成 token 時逐個輸出,而不是一次性生成完整序列,適合實時對話。
- 高效推理:通過優化 Transformer 架構(如減少注意力計算復雜度)和硬件加速(如 GPU),確保快速響應。
3.1 情感理解與表達
Westlake-Omni 在高質量中文情感語音數據集上訓練,具備以下能力:
- 情感理解:通過分析語音的音高、語速、音量等特征,識別用戶的情感狀態(如悲傷、興奮)。
- 情感生成:在生成語音時,調整輸出的語調和節奏,匹配目標情感。例如,回應“心情不好”時,生成帶有安慰語氣的語音。
- 上下文保持:通過 Transformer 的長上下文建模能力,維持對話的連貫性和情感一致性。
3.2 數據流與整體工作流程
FireflyArchitecture 的整體工作流程如下:
def encode(self, audios, audio_lengths):mels = self.spec_transform(audios)mel_lengths = audio_lengths // self.spec_transform.hop_lengthmel_masks = sequence_mask(mel_lengths, mels.shape[2])mels = mels * mel_masks[:, None, :].float()encoded_features = self.backbone(mels) * mel_masks[:, None, :].float()feature_lengths = mel_lengths // self.downsample_factorreturn self.quantizer.encode(encoded_features), feature_lengthsdef decode(self, indices, feature_lengths):z = self.quantizer.decode(indices) * mel_masks[:, None, :].float()x = self.head(z) * audio_masks[:, None, :].float()return x, audio_lengths
- 輸入:原始音頻波形([batch_size, 1, time_steps])和對應的長度(audio_lengths)。
- 梅爾頻譜圖轉換:
- 通過 LogMelSpectrogram 將音頻轉換為梅爾頻譜圖([batch_size, n_mels, time_frames])。
- 使用掩碼(sequence_mask)處理變長序列。
- 編碼:
- ConvNeXtEncoder 將梅爾頻譜圖編碼為高層次特征([batch_size, dim, reduced_time_frames])。
- DownsampleFiniteScalarQuantize 量化為離散索引([batch_size, n_groups * n_codebooks, further_reduced_time_frames])。
- 解碼:
- DownsampleFiniteScalarQuantize 將索引解碼為特征([batch_size, dim, time_frames])。
- HiFiGANGenerator 將特征轉換為音頻波形([batch_size, 1, time_steps])。
3.3?優勢與局限性
優勢
- 端到端設計:從語音輸入到語音輸出全程由單一模型處理,減少模塊間誤差。
- 低延遲:流式處理和增量生成適合實時交互。
- 情感能力:在中文情感語音交互方面表現出色,增強用戶體驗。
- 開源:公開代碼和模型權重,便于社區優化和定制。
局限性
- 數據集依賴:模型性能依賴于中文情感語音數據集的質量和多樣性,可能在非中文或特定方言場景下表現不佳。
- 計算資源:實時推理需要 GPU 支持,對硬件要求較高。
- 模態擴展:目前專注于語音和文本,尚未支持圖像或視頻輸入,功能相對單一。
- 開源文檔:官方文檔可能不夠詳細,需參考代碼深入理解。
與其他模型的對比
與 Qwen2.5-Omni()和 Mini-Omni()等模型相比,Westlake-Omni 的特點如下:
- 與 Qwen2.5-Omni 的對比:
- 相似點:兩者均為端到端多模態模型,支持文本和語音交互。
- 不同點:Qwen2.5-Omni 支持更多模態(包括圖像和視頻),而 Westlake-Omni 專注于中文情感語音,延遲更低,情感表達更強。
- 架構差異:Qwen2.5-Omni 采用 Thinker-Talker 架構,而 Westlake-Omni 強調離散表示的統一處理。
- 與 Mini-Omni 的對比:
- 相似點:兩者均為開源,專注于實時語音交互。
- 不同點:Mini-Omni 使用 Qwen2 作為語言骨干,規模較小,而 Westlake-Omni 更專注于中文情感場景,數據集更定制化。
使用頁面測試
輸入文本:
因為無法播放音頻,我截取控制臺輸出
>> Input: ?/tmp/gradio/ec6ab5438b1a8143d7033ff12cb6345f03c50a4a678d521572d599397d1182b0/input.wav 我并不喜歡現在的工作 audio+text
2025-05-12 12:58:33.412 | INFO ? ? | generate:generate_long:337 - First Token: 0.05658505391329527
? 3%|██▍ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| 102/4010 [00:05<03:38, 17.93it/s]
2025-05-12 12:58:39.203 | INFO ? ? | generate:generate_long:361 - generated: 103 tokens
Gen text: 嗯,也許可以試試一些新事物,找到喜歡的東西來放松自己.
>> Input: ?/tmp/gradio/ec6ab5438b1a8143d7033ff12cb6345f03c50a4a678d521572d599397d1182b0/input.wav 我想全職去打游戲,成為一名電競選手,但是家里人不同意 audio+text
2025-05-12 12:59:12.262 | INFO ? ? | generate:generate_long:337 - First Token: 0.05528050009161234
? 1%|█▍ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| 59/4010 [00:03<03:43, 17.67it/s]
2025-05-12 12:59:15.693 | INFO ? ? | generate:generate_long:361 - generated: 60 tokens
Gen text: 嗯,聽起來你面臨很大的支持.
>> Input: ?/tmp/gradio/ec6ab5438b1a8143d7033ff12cb6345f03c50a4a678d521572d599397d1182b0/input.wav 家里人不同意我去當電競選手 audio+text
2025-05-12 12:59:43.566 | INFO ? ? | generate:generate_long:337 - First Token: 0.05704664625227451
? 2%|█▊ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| 74/4010 [00:04<03:41, 17.79it/s]
2025-05-12 12:59:47.819 | INFO ? ? | generate:generate_long:361 - generated: 75 tokens
Gen text: 嗯,家人和朋友的意見確實很重要.