20/07/2019, 09:49

Ứng dụng Deep Learning đọc truyện ma như giọng MC Đình Soạn

Người viết: Phạm Văn Toàn Xin chào các bạn. Nhiều bạn đam mê truyện ma kinh dị hẳn không còn lạ lẫm gì với những audio truyện ma nổi tiếng của Nguyễn Ngọc Ngạn, Đình Soạn hay Hồng Nhung rồi đúng không. Tuy nhiên họ không phải truyện ma nào cũng kể. Và có lúc mình thích truyện ma ...

Ứng dụng Deep Learning đọc truyện ma

Người viết: Phạm Văn Toàn

Xin chào các bạn. Nhiều bạn đam mê truyện ma kinh dị hẳn không còn lạ lẫm gì với những audio truyện ma nổi tiếng của Nguyễn Ngọc Ngạn, Đình Soạn hay Hồng Nhung rồi đúng không.

Tuy nhiên họ không phải truyện ma nào cũng kể. Và có lúc mình thích truyện ma này, nhưng lại không bao giờ được nghe chính giọng của họ được. Thật là không thú vị phải không nào?

Nếu mà có một cách nào để thích nghe truyện gì thì họ phải đọc cho mình nghe một cách tự động thì tốt quá phải không? Vậy nên hôm nay mình sẽ hướng dẫn các bạn làm một series truyện ma siêu to khổng lồ như thế nhé.

OK giờ chúng ta bắt đầu thôi!

  Ứng dụng Deep Learning cho bài toán nhận diện chữ viết (OCR)
  Machine Translation với thuật toán Attention trong Deep Learning

Định hướng bài toán

Về cơ bản thì hôm nay mình sẽ hướng dẫn các bạn ứng dụng Deep Learning đọc truyện ma. (Chỉ là ví dụ thôi, các cháu có thể tự làm với bất kì loại truyện nào khác).

Phần lớn trong bài này nói đến công nghệ tổng hợp tiếng nói và các bước thực hiện trong một bài toán tổng hợp tiếng nói.

Với giọng đọc của MC Đình Soạn, mình sẽ sử dụng để làm hướng dẫn cho các bạn. Để thực hiện bài toán này chúng ta cần thực hiện các bước như sau:

  • Chuẩn bị dữ liệu: Giống như mọi bài toán khác thì bước chuẩn bị dữ liệu là vô cùng cần thiết. Trong bài này các bạn sẽ được thực hiện các bước từ đầu đến cuối để chuẩn bị cho việc training mô hình.
  • Tìm hiểu lý thuyết tổng hợp tiếng nói: Rõ ràng rằng chúng ta cần phải hiểu được cái mà chúng ta đang làm thì chúng ta mới tiến hành làm được phải không nào. Tìm hiểu lý thuyết và làm survey là một bước rất quan trọng trong quá trình làm việc trên thực tế.
  • Lựa chọn và hiểu được lý thuyết mô hình Tacotron2: Tacotron2 được coi là một trong những phương pháp tốt nhất hiện nay trong lĩnh vực tổng hợp tiếng nói. Chúng ta sẽ cùng nhau tìm hiểu chi tiết về phương pháp này trong các phần tiếp theo nhé.
  • Tiền xử lý dữ liệu và lựa chọn tham số: Việc tiền xử lý dữ liệu là bước không thể thiếu và quyết định khá nhiều đến độ chính xác của mô hình AI mà các cháu làm ra. Đặc biệt việc hiểu và lựa chọn các tham số sao cho phù hợp để training ra được mô hình tốt nhất là một điều mà các cháu nên tìm hiểu.
  • Training và đánh giá mô hình: Đây là bước tất nhiên là quan trọng trong quá trình thực hiện một bài toán AI.
  • Chạy thử kết quả: Tất nhiên là sau khi training thì cần thử nghiệm kết quả rồi phải không nào.
  • Hậu xử lý audio: Đây là việc khá quan trọng để có được một audio truyện ma hay.

Giờ chúng ta sẽ bắt đầu vào chi tiết của từng phần nhé!

Chuẩn bị dữ liệu

Bước 1: Thu thập dữ liệu mẫu

Bước này là bước quan trọng và cũng là bước mất nhiều thời gian nhất.

Để có được dữ liệu sạch thì các bạn phải bỏ công sức ra đi tìm những nguồn audio âm thanh có chất lượng thu âm tốt. Ở đây mình sử dụng giọng đọc của MC Đình Soạn – MC truyện ma mà mình khá thích để làm dữ liệu.

Các bạn có thể lên trang nghe đọc truyện để kiếm dữ liệu về. Mỗi một tập truyện dài của Đình Soạn có thể cho chúng ta gần chục giờ dữ liệu. Chỉ cần vài ba truyện là có đến mấy chục giờ dữ liệu thì cũng đủ để training một cái demo nho nhỏ.

Bước 2: Sinh text cho dữ liệu

Các bạn nhớ việc tải dữ liệu audio về thì dễ dàng thôi nhưng đó mới chỉ là bắt đầu của một câu truyện buồn thê lương, sầu thảm mang tên annotate dữ liệu.

Về cơ bản đề annotate dữ liệu cho bài toán Text To Speech thì không có cách nào khác là phải tự mình ghi lại text tương ứng với từng đoạn audio đó. Nếu các bạn tự làm việc này thì thật là quá sức tưởng tượng. Tuy nhiên bằng một vài thủ thuật nho nhỏ cũng sẽ đỡ hơn cho các cháu khá nhiều công sức.

Về cơ bản chúng ta sẽ sử dụng một thư viện speech to text để chuyển audio với thời gian tương ứng thành text. Tuy nhiên do độ chính xác của thư viện có thể chưa chuẩn xác nên cần chúng ta phải validate và sửa lại text cho chính xác.

Công việc này tuy khá mất thời gian nhưng còn đỡ hơn là việc chúng ta ngồi gõ lại từ đầu. Để làm được điều đó chúng ta sử dụng thư viện autosub.

Cài đặt đơn giản như sau:

Các bạn nhớ cài ffmpeg trước nhé. Sau khi cài đặt xong thì vào trong thư mục chứa các audio đọc truyện ma vừa mới tải về lúc nãy. Chạy từng truyện một.

Ví dụ với truyện ma_bup_be.mp3 thì chạy lệnh sau:

Đợi khoảng 1 phút cho nó chạy xong, các bạn sẽ thấy được một file dạng subtitle (ma_bup_be.srt) trong đó có thời gian bắt đầu và thời gian kết thúc với text tương ứng của từng câu.

Theo nhiều lần thí nghiệm của mình thì về mặt thời gian start và end của từng câu thì rất chính xác còn về text thì có câu chuẩn có câu không nên các bạn cần phải điều chỉnh lại nhé.

Có rất nhiều phần mềm hỗ trợ việc chỉnh sửa file subtitle nên các bạn phải chịu khó nghe kĩ lại rồi sửa cho đúng. Lười tải app thì có thể dùng trực tiếp bản online tại đây.

Bước 3: Cắt dữ liệu thành các file nhỏ

Do việc training text to speech sẽ phải tách dữ liệu thành từng cặp câu nhỏ nên cần phải cắt các cái file lớn kia thành các file nhỏ hơn nhé. Và chúng ta sẽ cần cắt theo thời gian bắt đầu và kết thúc trong file srt.

Và do đã tách ra thành nhiều file nhỏ nên chúng ta cần lưu text tương ứng với filename trong một file csv. Output của chúng ta sẽ có dạng như sau:

Để thực hiện điều này cần thực hiện như sau:

Chuẩn hoá dữ liệu

Sau khi đã chuẩn bị xong dữ liệu, bạn phải làm đến bước tiếp theo đó là chuẩn hoá. Việc chuẩn hoá này bao gồm chuẩn hoá text và chuẩn hoá audio.

Chuẩn hoá text

Về chuẩn hoá text có một số bước như convert từ chữ hoa về chữ thường, convert từ số sang chữ, convert thời gian, ngày tháng sang chữ…

Bước này gồm một vài hàm như sau, bạn có thể tham khảo hoặc custom thêm các hàm khác nữa nhé.

Sau khi các bạn chạy hàm normalize_text thì sẽ có kết quả của chuỗi được chuẩn hoá. Tiếp theo chúng ta sẽ đến một bước khá quan trọng đó là chuẩn hoá audio. Mình nhắc lại là đây là bước khá quan trọng nhé.

Chuẩn hoá audio

Về cơ bản thì muốn dùng được framework Tacotron 2 dưới đây thì các bạn cần phải thực hiện chuẩn hoá audio về theo format giống như tập dữ liệu tiếng Anh. Có một số đặc điểm như:

  • Sampling rate: 22050
  • Data format WAV Mono
  • Decoding PCMS16LE

Các bạn có thể sử dụng FFMPEG để thực hiện các bước chuẩn hoá này nhé.

Tìm hiểu về Tacotron 2

Vậy chúng ta đã vừa chuẩn bị xong dữ liệu nào rồi phải không.

Tiếp theo chúng ta sẽ đến phần chế biến các dữ liệu đó thành hình nào. Nhưng trước hết chúng ta cần phải hiểu lý thuyết cái đã nhé. Mô hình mà chúng ta sử dụng cho bài toán này đó là mô hình Tacotron2. Để hiểu rõ hơn về mô hình này chúng ta sẽ lướt qua một vài khái niệm trong đó nhé:

Tacotron 2 là gì?

Tacotron 2 là một mạng nơ-ron nhân tạo được phát minh ra bởi Google vào cuối năm 2018 để giải quyết vấn đề tổng hợp giọng nói với một chất lượng có thể coi là bá cháy nhất trong những Framework được public hiện tại về Text To Speech.

Để hiểu được độ bá cháy của nó thế nào mình mời các bạn xem qua chính các kết quả của nhóm nghiên cứu sau khi thử nghiệm trên tập dữ liệu của tiếng Anh tại đây.

Và mô hình chung của Tacotron 2 có thể được minh hoạ trong sơ đồ sau:

Nhìn sơ đồ trên khá khó hiểu. Để mình tóm tắt lại cho các cháu dễ hiểu nhé:

Kiến trúc tacontron 2 sử dụng một mô hình Sequence to Sequence rất thông dụng trong các bài toán dịch tự động hay image captioning. Tuy nhiên đầu vào của chúng ta là một chuỗi các kí tự và đầu ra tương ứng là một chuỗi các features (ở đây là mel spectrogram). Nhưng features này có đặc điểm là nó không chỉ biểu diễn được độ chính xác của phát âm của các từ mà còn biểu diễn được nhiều sự tính chất khác của âm thanh con người như âm lượng, tốc độ và ngữ điệu.

Để làm được điều này người ta sử dụng một cơ chế đó là Location sensitive attention. Kiến trúc này mình sẽ giải thích kĩ hơn trong phần tiếp theo. Sau đó các đặc trưng này được đưa vào một mạng vocoder như Wavenet để chuyển từ mel spectrogram sang spectrogram và chuyển thành audio.

Đại ý kiến trúc của chúng ta là như vậy. Tacotron 2 sẽ bao gồm 2 phần đó là Seq2Seq để chuyển từ chuỗi các kí tự sang đặc trưng mel spectrogram và một phần nữa để chuyển mel spectrogram đó thành audio thông qua một wave-net model.

Giờ chúng ta đi tìm hiểu chi tiết từng phần một nhé!

Mạng convert Text sang Mel Spectrogram

Như mình đã trình bày phía trên thì dây chính là phần mà chúng ta sẽ xem xét đầu tiên. Làm sao chuyển từ mỗi chuỗi các kí tự sáng một chuỗi các đặc trưng mel spectrograms.

Có một điểm thú vị của Tacotron 2 đó là bạn có thể training độc lập hai mô hình Seq2seq này với mô hình Wavenet phía sau nên hôm nay chúng ta sẽ đi làm rõ về phần đầu tiên nhé.

Mô hình này là một mạng nơ-ron kết hợp của 3 thành phần là encoder-attention-decoder trong đó sử dụng cơ chế Location sensitive attention với mục đích đã nói phía trên. Sơ đồ chung của nó có thể diễn tả trong hình bên dưới. Giờ chúng ta cùng tìm hiểu chi tiết về các phần này nhé

Encoder

Phần đầu tiên là một Encoder chuyển đổi chuỗi ký tự thành vector word embeding. Các đặc trưng này sau đó được sử dụng để bộ Decoder dự đoán các phổ. Trong trường hợp bài toán của chúng ta cần phải sử dụng tập từ tiếng Việt nên các kí tự mà chúng ta sử dụng cũng là tập các kí tự của tiếng Việt.

Trong sơ đồ trên thì Encoder chính là thành phần màu xanh dương phía bên trái, nó bao gồm các mạng con như sau:

  • Mạng Character Embeding sử dụng để mã hoá kí tự, kích thước của mạng này tuỳ thuộc vào số lượng từ mà chúng ta config trong từ điển.
  • Mạng 3 Conv sau khi kết quả đầu ra của mạng embeding sẽ được đưa vào 3 lớp Convolution 1D và mỗi lớp trong số đó chứa 512 filters kích thước 5 x 1. Sau cùng là lớp Batch Normalization và hàm kích hoạt ReLU.
  • Mạng LSTM Đầu ra của lớp tích chập cuối cùng được đưa vào một mạng LSTM hai chiều chứa 512 units (256 units cho mỗi chiều) để sinh ra các đặc trưng được encoded.

Attention

Mục đích của lớp Attention (màu xám trên hình phía trên) là giúp cho mô hình focus vào không chỉ các đặc trưng ở các step trước đó mà còn là cả đặc trưng tại vị trí hiện tại. Giải thích nhanh một chút nhé.

Giả sử chúng ta có dữ liệu x=x1,x2,x3,...xN sau khi di qua mạng encoder phía trên cho ra một chuỗi kết quả h=h1,h2,h3.hN.

Một vector A(i)=Attention(s(i-1),A(i-1),h) được gọi là alignment trong đó thì s(i1) là trạng thái decoding trước đó và A(i-1) là alignment của step trước đó.

Hàm Attention thường được tính toán bằng cách tính điểm riêng các thành phần trong h một cách độc lập sau đó normalize kết quả.

Chúng ta định nghĩa hai hàm đặc trưng sau:

G(i) = A(i,0) h(0) + A(i,1) h(1) + ……. + A(i,N) h(N)

Y(i) = Generate (s(i-1), G(i))

cuối cùng trạng thái tiếp theo được tính toán dựa vào các hàm trên với cơ chế Attention

s(i) = LSTM (s(i-1), G(i), Y(i))

Phần tiếp theo chúng ta sẽ cùng tìm hiểu về thành phần cuối cùng (màu da cam) được gọi là Decoder.

Decoder

Mục đích của mạng decoder là sinh ra mel spectrogram từ kết quả đầu ra của bước trước. Đầu tiên phải xét đến mạng pre-net với 2 fully connected layers gồm 256 units và hàm kích hoạt ReLU. Đầu ra của mạng pre-net được concatnate với đầu ra của mạng attention và được đưa qua 2 lớp LSTM với 1024 units.

Cuối cùng để predict ra mel spectrogram thì vector đầu ra được đưa qua 5 layers convolution được gọi là post-net. Chắc là lý thuyết đến như vậy là đủ rồi phải không các bạn. Giờ chúng ta bắt tay ngay vào phần thực hành thôi nhé.

Training mô hình

Rất khuyến khích nếu bạn nào đọc hết phần lý thuyết bên trên nhưng cũng đã đến lúc chúng ta cần phải đi sâu vào thực tế hơn một chút rồi đó.

Ở đây để cho dễ dàng chúng ta sẽ sử dụng Pytorch để training mô hình Tacotron 2 này. Một trong những repo implement mô hình này tuyệt vời nhất đó là NVIDIA/tacontron-2.

Trong đó chúng ta cùng đi sâu phân tích cách họ implement mô hình nhé. Các bạn mở file model.py ra sẽ thấy toàn bộ các phần code implement đến mô hình. Mình rất khuyến khích các bạn thử dành ra một vài giờ để ngồi đọc code của họ xem họ xử lý ra sao. Tất cả các phần họ sử dụng đã được trình bày ở phần lý thuyết phía trên nhưng có vẻ như việc đọc code sẽ dễ hiểu hơn rất nhiều so với việc đọc lý thuyết phải không nào.