# AI音樂幫手
[流程圖](#流程圖)
- [一. 資料收集](#一-資料收集)
- [1. 收集資料](#1-從各種不同來源收集資料)
- [2. 音樂分類](#2-將音樂進行分類各100首,時長30秒以上)
- [二. 資料處理](#二-資料處理)
- [1-自動生成文本和轉檔](#1-自動生成文本和轉檔)
- [2-音樂曲風分類](#2-音樂曲風分類)
- [三. 使用MusicGen模型進行訓練](#三-使用Musicgen-model-進行訓練)
- [1-數據預處理和轉換](#1-數據預處理和轉換)
- [2-模型訓練](#2-模型訓練)
- [四. 生成音樂](#四-生成音樂)
[改進](#改進)
[問題和討論](#問題和討論)
[結論](#結論)
[使用手冊](#使用手冊)
- [前置安裝](#前置安裝)
# 流程圖

## 一. 資料收集
### 1. 從各種不同來源收集資料
- [Pixabay](https://pixabay.com/zh/music/)
- [Huggingface](https://huggingface.co/datasets/breadlicker45/bread-midi-dataset/tree/main)
- [Magenta](https://magenta.tensorflow.org/datasets/maestro)
- [Youtube](https://www.youtube.com)
- [Purple Planet](https://www.purple-planet.com/)

### 2. 將音樂進行分類:各100首,時長30秒以上
- 藍調 blues
- 古典 classical
- 鄉村 country
- 迪斯可 disco
- 嘻哈 hiphop
- 爵士 jazz
- 金屬 metal
- 流行 pop
- 雷鬼 reggae
- 搖滾 rock
- 未知 unknow: 尚未分類的音樂將放置在unknow資料夾

## 二. 資料處理
### 1. 自動生成文本和轉檔
- 將midi、mp3等音樂格式統一轉成**wav**檔
- 將轉換後的音檔生成相對應的文本描述,包括音檔的名稱、風格等描述性內容。
### 2. 音樂曲風分類
- 使用librosa提取**MFCC**特徵
- 梅爾頻率倒頻譜係數(Mel Frequency Cepstral Coefficients,簡稱MFCC)
- MFCC通過模仿人耳對聲音頻率的非線性感知,提取音頻信號的特徵,
廣泛用於分析和識別過程。
- MFCC提取的**特徵**:
- 音頻頻譜的形狀
- 頻譜的能量分佈
- 時變特徵
- 語音信號的形態特徵
- 音色質感
- 使用concurrent.futures.ThreadPoolExecutor來並行處理文件
- 利用線程池來並行執行任務,大大加快執行速度
- 切割成訓練集、測試集
- 新增了一個新維度用以符合卷積層的輸入要求
- 因為MFCC的特徵本身是二維的(時間步長 × MFCC係數)
- 增加的維度使數據的形狀變為(樣本數, 時間步長, MFCC係數, 1)
```python!
import numpy as np
from sklearn.model_selection import train_test_split
def prepare_dataset(test_size, validation_size):
X, y = load_data("D:\\Senior Project\\save\\music_data.json")
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train,
test_size=validation_size)
X_train = X_train[..., np.newaxis]
X_val = X_val[..., np.newaxis]
X_test = X_test[..., np.newaxis]
return X_train, X_val, X_test, y_train, y_val, y_test
X_train, X_val, X_test, y_train, y_val, y_test = prepare_dataset(0.25, 0.2)
input_shape = X_train.shape[1:]
print(input_shape)
```
- 建構**CNN Model**
```python!
model = Sequential([
Input(shape=input_shape),
Conv2D(64, (3, 3), activation="relu"),
MaxPool2D((3, 3), strides=(2, 2), padding="same"),
BatchNormalization(),
Conv2D(32, (3, 3), activation="relu"),
MaxPool2D((3, 3), strides=(2, 2), padding="same"),
BatchNormalization(),
Conv2D(32, (2, 2), activation="relu"),
MaxPool2D((2, 2), strides=(2, 2), padding="same"),
BatchNormalization(),
Conv2D(16, (1, 1), activation="relu"),
MaxPool2D((1, 1), strides=(2, 2), padding="same"),
BatchNormalization(),
Flatten(),
Dense(64, activation="relu"),
Dropout(0.3),
Dense(10, activation="softmax")
])
model.summary()
```
- 進行訓練
```python!
model.compile(optimizer=tfa.optimizers.AdamW(learning_rate=1e-4),
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
hist = model.fit(X_train, y_train,
validation_data=(X_val, y_val),
epochs=50,
batch_size=32,
verbose=0,
callbacks=[SingleLineProgressCallback()])
print(f"Test accuracy: {model.evaluate(X_test, y_test, verbose=0)[1]:.4f}")
```
- 進行音樂曲風分類並生成相對應文本
## 三. 使用**Musicgen model** 進行訓練
### 1. 數據預處理和轉換
- 加載音檔
- 將採樣率設為44100
- 將通道設置成單聲道
- 將音檔裁切成30秒
- 使用compression model進行音檔的壓縮和編碼
- 進行one-hot編碼
```python!
def preprocess_audio(audio_path, model: MusicGen, duration: int = 30):
wav, sr = torchaudio.load(audio_path)
wav = torchaudio.functional.resample(wav, sr, 44100)
wav = wav.mean(dim=0, keepdim=True)
if wav.shape[1] < model.sample_rate * duration:
return None
end_sample = int(model.sample_rate * duration)
start_sample = random.randrange(0, max(wav.shape[1] - end_sample, 1))
wav = wav[:, start_sample : start_sample + end_sample]
assert wav.shape[0] == 1
wav = wav.cuda()
wav = wav.unsqueeze(1)
with torch.no_grad():
gen_audio = model.compression_model.encode(wav)
codes, scale = gen_audio
assert scale is None
return codes
def one_hot_encode(tensor, num_classes=2048):
shape = tensor.shape
one_hot = torch.zeros(*shape, num_classes, device=tensor.device)
one_hot.scatter_(2, tensor.unsqueeze(-1), 1)
return one_hot
```
### 2. 模型訓練
## 四. 生成音樂
- 讀入訓練好的模型和權重
- 設置生成的參數
- 使用預設的參數和準備好的token進行循環生成
- 拼接生成結果
- 進行解碼
- 保存生成的音樂
# 改進
### 1. 自動生成文本和轉檔
在訓練過程中,音樂的WAV檔案及相關文本的TXT檔案是必須的。為了簡化預處理階段,我們開發了一個功能,能夠自動將MP3、MIDI等格式的文件轉換成WAV格式。同時,該功能還會根據文件所在的目錄結構自動生成相應的文本檔案。這樣,我們就無需手動創建新的文本文件或進行格式轉換,從而大大節省了準備數據的時間和工作量。
### 2. 音樂風格分類器
在搜集音樂資料的過程中,我們致力於選擇可自由使用的曲目,以規避版權問題。然而,我們偶爾會遇到未經分類或文件名呈現亂碼的音檔,這對於資料收集工作帶來了不小的挑戰。為了解決這一問題,我們在AI音樂助手中加入了一項新功能:音樂風格辨別器。透過這個工具,我們能夠有效地對音檔進行風格分類,進一步優化我們的資料整理流程。
### 3. 音樂訓練框架
在我們推進音樂生成的工作中,主要依賴於一款名為MusicGen的尖端模型,該模型專為音樂創作的自動化而設計,旨在令音樂生成變得更加便捷、迅速。MusicGen模型憑借其卓越的音樂理解能力和優異的生成質量而聞名,其生成的音樂質量之高,甚至足以應用於音樂信息檢索(MIR)領域。然而,該模型僅提供了預訓練的模型參數,未開放自定義訓練的接口。為了使研究人員和開發者能夠根據自身的音樂需求和風格偏好,創建定制的AI音樂助理,我們開發了一套全面的訓練框架。該框架深入剖析了MusicGen模型的架構及其運作原理,精煉出了核心音樂生成機制,并在此基礎上,擴充了多項功能模塊,包括音頻的預處理、動態數據加載以及自定義訓練參數設置等。藉助於自動混合精度訓練和梯度累積技術,這套訓練框架使使用者能夠毫不費力地將自己的音樂數據集投入模型進行訓練,從而實現個性化音樂創作。
# 問題和討論
### 1. 高性能硬件要求
在模型訓練階段,我們經常面臨電腦內存不足的問題,這阻礙了模型的執行和開發進度。為了降低對高性能硬件的依賴並加速訓練過程,我們採取了優化數據加載和模型結構的策略。然而,當處理大量音頻文件時,內存溢出的問題仍然存在,顯示出進一步優化的必要性。
### 2. 數據收集的複雜性
音樂數據的收集過程中,我們面臨著版權、音質不佳、缺乏分類和元數據亂碼等問題。此外,為音頻文件手動生成匹配的文本標籤增加了額外的工作量。為解決這些問題,我們改善了數據預處理和清洗流程,並採用自動化工具提高效率。
### 3. 路徑配置問題
程式執行中需要手動配置多個路徑,這一過程繁瑣且易出錯。為提高用戶體驗,我們正在開發更加友好的路徑配置系統,透過自動化探測和智能提示,簡化路徑設置過程。
### 4. 系統兼容性限制
我們在項目中使用了triton這一深度學習優化套件,但遇到了其不支持Windows操作系統的問題。雖然網路上有修改版本使其能在Windows上運行,但存在版本兼容問題。我們目前的解決方案是在虛擬機中安裝Linux系統,以規避兼容性問題,同時我們也在考慮對相關依賴進行調整,以適應更廣泛的開發環境。
### 5. Mamba model
將模型中的Transformer架構替換為最新發布的Mamba架構,可能為處理速度、長序列數據處理能力及計算資源消耗帶來顯著改進。Mamba模型,以其獨特的選擇性信息傳播機制和線性時間複雜度,不僅在語言模型測試中展現出優異的性能,甚至在推理速度上實現了相較於Transformer高達五倍的提速。這種改進尤其適用於要求實時響應和處理大規模數據集的應用場景。同時,Mamba的高效數據處理能力對於生成式AI服務和長文本生成等任務來說,也提供了新的可能性。但實現這一轉變需要對Mamba架構有深刻的理解,目前我們的技術能力尚不足以對其進行更動。
### 6. Music Transformer
在訓練過程中,為了有效地縮短訓練所需的時間,我曾嘗試探索同時生成多個音樂段落的可能性,目的是在不損失音質的前提下提高效率。然而,儘管單個段落的音質達到了預期的高水準,但段落與段落之間的連貫性卻未能達到理想的流暢度。基於這一發現,我計劃嘗試運用Google開發的Music Transformer模型來進行改進,希望通過其先進的多頭自注意力機制來優化段落之間的過渡,從而在保證音樂質量的同時,實現段落間的無縫銜接。
# 結論
根據Meta、google等企業研究,我們可以知道Transformer、Encodec等模型在音樂創作領域有著巨大的潛力。這些模型不僅能理解音樂的結構與模式,還能創作出具有豐富音樂性的新作品,開拓了機器創作音樂的新視野。在我們的專題過程中也面臨了諸多挑戰,如模型訓練和音樂評估問題,凸顯了音樂生成領域尚存的諸多難題與未來研究的必要性。儘管我們取得了初步成果,但音樂生成的探索之路仍舊漫長。未來工作將著眼於提升生成音樂的質量與多樣性,優化模型效能,並探索將生成音樂運用於實際的可能性。我們相信,通過持續的研究與創新,將會在音樂生成領域達成更多突破。
# 使用手冊
## 前置安裝
### 一. 建置linux環境 (如想直接在windows上執行,請略過此步驟)
- 安裝VMware
- 下載ubuntu
- 建置虛擬機
### 二. 所需安裝軟體和套件
#### [1. python 3.10.12](https://www.python.org/downloads/windows/)
#### [2. cuda 11.8](https://developer.nvidia.com/cuda-11-8-0-download-archive?target_os=Windows)
#### 3. pytorch
- ( pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cu118)
-
#### [4. ffmpeg](https://www.gyan.dev/ffmpeg/builds/)
#### 5. xformers
- (pip3 install -U xformers==0.0.22.post2+cu118 --index-url https://download.pytorch.org/whl/cu118)
#### 6. triton (如在windows上執行,請略過此步驟)
- (pip install https://huggingface.co/r4ziel/xformers_pre_built/resolve/main/triton-2.0.0-cp310-cp310-win_amd64.whl)
#### 7. [安裝其餘所需套件]
---
## 使用方式
### 一. 設定音檔位置
#### 1. 建立存放音檔的資料夾
#### 2. 將音檔進行分類
- 目前預設有disco、metal、reggae、blues、rock、classical、jazz、hiphop、country、pop、unknow等等,共11種
- 可根據自己需求進行添加或刪減分類,將不清楚分類且檔名無法辨別的音檔放置到unknow
- 如果音檔名稱為可辨識且正常,但沒有特別的分類,可直接放在主目錄

### 二. 修改路徑
#### 1. 將程式中base_dir修改成音檔存放的位置(主目錄)

### 三. 執行
---