本記事は、
これまでに構築した GPU 対応 PyTorch 環境を前提に、DeepFilterNet3 の GPU 動作検証と動画音声のノイズ除去テストを行った記録 です。
前回の確認で、DenoiserがGPUを使用して動作する環境構築と実際にノイズ除去を試すところまで行いました。ffmpegでモノラルに変換した効果もあってか、Denoiserでのノイズ除去と音量ダイナミクスの安定化にはそれなりに効果があることが分かりました。(本当は解析して数値で記載するほうが分かり易いのですが、現状は私の個人的な感想です。)
ところで補正後の音声にもまだマイクに何かがぶつかるような音がありました。
自動でどこまでできるか、も確認したいので、衝撃音に強いらしいDeepFilterNetを試すことにしました。
記事内のディレクトリの位置や名前、ファイル名などは私が自分で利用しやすいように変更したりしていますので、試される場合はご自身の環境に合わせて読み替えてください。
1.DeepFilterNet3インストール
今回も前回の仮想環境を利用します。
$ conda activate denoiserenv
・deepfilternet 本体をインストール
$ pip install deepfilternet
・pyファイル格納用にディレクトリを作成しました。
$ mkdir ~/scripts
$ cd ~/scripts
・コードを書いて.pyファイルに保存(ここではファイル名をtest_dfn3.pyにしました。)
import torch
from df.enhance import enhance, init_df, load_audio, save_audio
import os
# 入力ファイル(今回使いたいファイル)
INPUT_WAV = os.path.expanduser(
"~/denoiser_test/denoised_wavs/lecture_raw_enhanced.wav"
)
# 出力ファイル(DFN3通した結果)
OUTPUT_WAV = os.path.expanduser(
"~/denoiser_test/denoised_wavs/lecture_raw_enhanced_dfn3.wav"
)
# 1チャンクの長さ(秒)
CHUNK_SECONDS = 600 # 10分。心配なら 300(5分) にしてもOK
def main():
print("PyTorch version:", torch.__version__)
print("CUDA available:", torch.cuda.is_available())
# DeepFilterNet 初期化(標準で DeepFilterNet3)
model, df_state, _ = init_df()
print("Model sample rate:", df_state.sr())
print("Model device before .to():", next(model.parameters()).device)
# GPUへ
if torch.cuda.is_available():
model = model.to("cuda")
print("Model device after .to():", next(model.parameters()).device)
else:
print("CUDA not available → CPU動作になります")
# 音声読み込み(モデルのサンプリングレートに合わせてロード)
print("Loading:", INPUT_WAV)
audio, sr = load_audio(INPUT_WAV, sr=df_state.sr())
# audio: [channels, samples]
print("Input sr:", sr, "Shape:", audio.shape)
# モノラル前提なので 1ch にして扱う
audio = audio.squeeze(0) # [samples]
total_samples = audio.shape[0]
chunk_samples = CHUNK_SECONDS * df_state.sr()
print(f"Total samples: {total_samples}")
print(f"Chunk samples: {chunk_samples} ({CHUNK_SECONDS} sec)")
enhanced_chunks = []
start = 0
chunk_idx = 0
with torch.no_grad():
while start < total_samples:
end = min(start + chunk_samples, total_samples)
chunk_idx += 1
print(f"Processing chunk {chunk_idx}: samples {start} - {end}")
# [1, chunk_len] の形に戻す
chunk = audio[start:end].unsqueeze(0)
# DFN3 でノイズ除去
enhanced_chunk = enhance(model, df_state, chunk)
# CPU側に集めておく
enhanced_chunk = enhanced_chunk.squeeze(0).cpu()
enhanced_chunks.append(enhanced_chunk)
start = end
# チャンクを結合
enhanced_full = torch.cat(enhanced_chunks, dim=-1)
print("Enhanced total samples:", enhanced_full.shape[-1])
# 保存
save_audio(OUTPUT_WAV, enhanced_full, df_state.sr())
print("Saved:", OUTPUT_WAV)
if __name__ == "__main__":
main()
実行します。
$ python test_dfn3.py
私の環境ではこれで無事動作しました。
効果があったか、というと今回は”微妙”と言わざるを得ない結果でした。
ただ、悪くなった部分は見受けられなかったので、
いったん以下のようなフローにしようと思います。
mp4 → ffmpegで音声抽出(WAV)
↓
ステレオ → モノラル(整える)
↓
DFN3(衝撃音・接触音・瞬間ノイズ対策)
↓
Denoiser(背景ノイズ・ブレス音を軽減、明瞭度UP)
↓
ffmpegで動画と合成
次回はこのフローで明瞭な咳払い入りの音声がどれくらい補正されるかを試してみます。