Tập đoàn OVH. Cách xây dựng ứng dụng Speech-To-Text với Python (1/3)

Chương trình Chuyển giọng nói thành văn bản của bạn sẽ có thể nhận bản ghi âm khi kết thúc bài viết đầu tiên này và tạo bản ghi của nó

Mã cuối cùng của ứng dụng có thể truy cập được trong kho lưu trữ GitHub chuyên dụng của chúng tôi

Tổng quan về ứng dụng cuối cùng của chúng tôi

Tổng quan về chương trình Speech-To-Text gần đây nhất của chúng tôi

Khách quan

Chúng ta đã xem trong các hướng dẫn sổ ghi chép trước về cách chuyển lời nói thành văn bản, cách chấm câu trong bản ghi, cách tóm tắt, cách xác định người nói, cách tạo phụ đề video và cách quản lý các vấn đề về bộ nhớ có thể xảy ra.

Bây giờ chúng ta đã biết cách thực hiện mọi thứ, hãy sử dụng Python để kết hợp các tính năng này vào ứng dụng Chuyển giọng nói thành văn bản

Nếu bạn không quen với Streamlit, một khung công tác Python chuyển đổi các tập lệnh thành các ứng dụng web có thể chia sẻ, đừng lo lắng;

Cấu trúc của bài viết này là như sau

  • Nhập mã từ các hướng dẫn trước
  • Viết ứng dụng Streamlit
  • Chạy ứng dụng của bạn

Chúng ta sẽ tìm hiểu cách sử dụng hình ảnh Docker tùy chỉnh để triển khai các ứng dụng Streamlit cũng như cách xây dựng và sử dụng một số tính năng nâng cao hơn (viết nhật ký, tóm tắt, chấm câu, v.v. ) trong các bài viết tiếp theo

Chúng tôi khuyên bạn nên đọc sổ ghi chép trước vì bài viết này sử dụng mã đã được trình bày trong các hướng dẫn về sổ ghi chép trước đó, vì vậy chúng tôi sẽ không xem xét ứng dụng của nó ở đây

Nhập mã từ các bài học trước 1. Cấu hình môi trường

Tạo một tệp có tên là yêu cầu và sau đó hãy tạo môi trường Python của chúng tôi. Chúng tôi sẽ có thể chỉ định từng phiên bản của các thư viện cần thiết cho dự án Bài phát biểu thành văn bản của chúng tôi bằng cách thêm văn bản sau vào tệp

_10

Sau đó, bạn có thể cài đặt tất cả các thành phần này chỉ bằng một lệnh bằng cách mở terminal và gõ lệnh sau

________thứ mười hai. Nhập thư viện

Tạo một tệp có tên ứng dụng. py và nhập các thư viện cần thiết mà chúng tôi đã sử dụng trong sổ ghi chép sau khi môi trường của bạn đã sẵn sàng

Chúng sẽ cho phép chúng tôi thao tác với các tệp âm thanh, thời gian và mô hình trí tuệ nhân tạo, trong số những thứ khác

# Models
import torch
from transformers import Wav2Vec2Processor, HubertForCTC

# Audio Manipulation
import audioread
import librosa
from pydub import AudioSegment, silence
import youtube_dl
from youtube_dl import DownloadError

# Others
from datetime import timedelta
import os
import streamlit as st
import time
3. Chức năng

Chúng tôi cũng cần sử dụng một số chức năng trước đây, một số chức năng mà bạn có thể quen thuộc

Hãy nhớ rằng các hướng dẫn sổ ghi chép bao gồm tất cả các mã này một cách chi tiết. Vì vậy, chúng tôi sẽ không đi qua lợi ích của nó một lần nữa ở đây

Hãy bắt đầu bằng cách phát triển chức năng cho phép phiên âm một đoạn âm thanh

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()

Tiếp theo, hãy phát triển bốn chức năng kích hoạt phương pháp phát hiện im lặng mà chúng tôi đã mô tả trong hướng dẫn sổ tay đầu tiên

Có được dấu thời gian của sự im lặng

def detect_silences(audio):

    # Get Decibels (dB) so silences detection depends on the audio instead of a fixed value
    dbfs = audio.dBFS

    # Get silences timestamps > 750ms
    silence_list = silence.detect_silence(audio, min_silence_len=750, silence_thresh=dbfs-14)

    return silence_list

Lấy giá trị trung bình của dấu thời gian

_15

Tạo phân phối thường xuyên hợp nhất dấu thời gian dựa trên các giá trị của min_space và max_space

_16

tùy thuộc vào giá trị của min_space và max_space, tự động "cắt thời gian" danh sách im lặng cho đến khi giá trị kết thúc

_17

Tạo một chức năng để loại bỏ các đoạn âm thanh và âm thanh khỏi thư mục nơi chúng được lưu để chúng tôi không giữ chúng sau khi sao chép

1. Định cấu hình ứng dụng bằng cách viết mã ứng dụng Streamlit

Chức năng cho phép cấu hình ứng dụng hiện có thể được tạo; . Đây là hành động

_19

Như bạn có thể thấy, thư mục gốc của thư mục mẹ là nơi đặt thư mục dữ liệu này (được biểu thị bằng. /ký hiệu). Vì AI Deploy đã tạo thư mục này nên nó sẽ chỉ được tạo nếu ứng dụng được khởi chạy cục bộ trên máy tính của bạn

Chúng tôi khuyên bạn không nên thay đổi vị trí của thư mục dữ liệu (. /). Khả năng chuyển đổi giữa chạy ứng dụng cục bộ và trên AI Deploy được cung cấp bởi vị trí này

2. Khởi động công cụ chuyển lời nói thành văn bản

Tạo một chức năng cho phép tải mô hình chuyển lời nói thành văn bản

Ban đầu, chúng tôi chỉ nhập mô hình sao chép;

Ở đây, trường hợp sử dụng là nhận dạng giọng nói tiếng Anh, nhưng bạn có thể thực hiện bằng ngôn ngữ khác nhờ một trong nhiều mẫu có sẵn trên trang web Ôm mặt. Tuy nhiên, hãy nhớ rằng bạn sẽ không thể kết hợp nó với một số mô hình mà chúng tôi sẽ sử dụng trong bài viết tiếp theo vì một số mô hình chỉ hoạt động trên bảng điểm tiếng Anh

________mười

Ở đây, chúng tôi sử dụng @st. bộ đệm với cờ đột biến đầu ra cho phép. Do đó, lần sau khi chúng ta gọi hàm (trong khi làm mới ứng dụng), Streamlit sẽ biết nó có thể bỏ qua chức năng này vì (các) mô hình đã được nhập một lần (trong quá trình khởi chạy ứng dụng), do đó không cần tốn thời gian tải lại

Đối với một mô hình, đây không phải là vấn đề vì thời gian tải xuống vẫn còn khá nhanh, nhưng đối với một mô hình khác, đây là một vấn đề vì thời gian tải xuống vẫn còn khá chậm vì nó phụ thuộc vào một số yếu tố, chẳng hạn như kết nối Internet của chúng tôi, khi khởi tạo . Nhưng thời gian khởi tạo này có thể lâu hơn với tất cả các dòng máy chúng tôi định tải trong bài viết sau, điều này sẽ gây khó chịu

Vì điều này, chúng tôi sẽ đề xuất giải pháp cho vấn đề này trong một bài đăng trên blog trong tương lai

3. Nhận tệp âm thanh

Khi mô hình đã được tải, chúng tôi phải sử dụng tệp âm thanh để mô hình hoạt động

Chúng tôi sẽ triển khai hai tính năng để trợ giúp việc này. cái đầu tiên sẽ cho phép người dùng nhập tệp âm thanh của riêng họ. Với tùy chọn thứ hai, anh ấy có thể chỉ định URL video mà anh ấy muốn lấy bản ghi

3. 1Cho phép người dùng tải lên tệp MP3, MP4 hoặc WAV

một st. tiện ích file_uploader() sẽ cho phép người dùng tải lên tệp âm thanh của riêng họ

pip install -r requirements.txt
1

Như bạn có thể thấy, chúng tôi bắt đầu quá trình sao chép bằng cách gọi hàm phiên mã () mà chúng tôi sẽ sớm tạo nếu biến upload_file không phải là Không có, cho biết rằng người dùng đã tải lên tệp âm thanh

3. 2 sao chép video YouTube

Tạo một tính năng cho phép tải xuống âm thanh từ các liên kết YouTube hợp pháp

________thứ mười hai

Tính năng này có thể không khả dụng để thực thi cục bộ nếu bạn không phải là quản trị viên của máy tính

Tiếp theo, chúng ta phải hiển thị một thành phần cho phép người dùng chỉ định URL mà họ muốn phiên âm

Vì có widget text_input() nên chúng ta làm được. Người dùng có thể nhập URL của video mà anh ta quan tâm và chúng tôi sẽ nhanh chóng xác minh nó. Chúng tôi cố gắng trích xuất âm thanh từ URL của video và sau đó sao chép âm thanh đó nếu liên kết đã nhập có vẻ chính xác (chứa mẫu của liên kết YouTube. "youtube")

Chức năng sau đây thực hiện điều này

pip install -r requirements.txt
34. Phiên âm các tập tin âm thanh

Các chức năng kết nối phần lớn những chức năng chúng tôi đã xác định bây giờ phải được viết

Chúng tôi bắt đầu bằng cách viết mã cho hàm init_transcription(), chức năng này cảnh báo người dùng rằng quá trình sao chép tệp âm thanh đang bắt đầu và sẽ đi từ giây bắt đầu đến giây kết thúc. Mặc dù hiện tại không đặc biệt thú vị vì các giá trị này tương ứng với các đầu thời gian của âm thanh (số 0 và độ dài âm thanh), nhưng chúng sẽ hữu ích trong phần sau

Srt_text và save_results, hai biến mà chúng ta cũng sẽ sử dụng trong bài viết tiếp theo, nằm trong số những biến được khởi tạo bởi hàm này. Đừng băn khoăn về chúng vào lúc này

pip install -r requirements.txt
4

Chúng tôi đã có các chức năng để phiên âm tệp âm thanh và thực hiện phương pháp phát hiện khoảng lặng, nhưng bây giờ chúng tôi cần liên kết tất cả các chức năng này lại với nhau. Chúng ta có thể thực hiện điều này bằng cách sử dụng chức năng phiên mã_non_diarization()

pip install -r requirements.txt
5

Bạn sẽ thấy rằng hàm này gọi hàm display_transcription(), hàm này hiển thị các thành phần thích hợp dựa trên các tham số do người dùng chọn

Chúng ta sẽ chỉnh sửa chức năng này ở bài viết sau để có thể xử lý các trường hợp hiển thị khác nhau, tùy thuộc vào tham số đã chọn, do hiện tại hiển thị là cơ bản do chúng ta chưa thêm tham số của người dùng

Bạn có thể đưa nó vào ứng dụng của mình

pip install -r requirements.txt
6

Các bước duy nhất còn lại là hiển thị tất cả các phần tử và liên kết chúng lại với nhau bằng hàm phiên mã ()

pip install -r requirements.txt
7

Chức năng khổng lồ này, gần như biên dịch tất cả các chức năng đã triển khai, giống với khối mã chính của chúng tôi

Đầu tiên, nó trả về kích thước của tệp âm thanh và cho phép người dùng phát tệp đó bằng một tiện ích có tên st. audio() hiển thị trình phát âm thanh. Phiên âm sau đó sẽ bắt đầu nếu độ dài âm thanh lớn hơn 0 giây và người dùng nhấp vào nút "Phiên âm"

Tất cả các kịch bản được chứa trong một st. spinner(), được hiển thị dưới dạng loading spinner trên ứng dụng để người dùng có thể thấy rằng mã đang chạy

Chúng tôi khởi tạo một số biến trong mã này và vì chúng tôi hiện không tạo phụ đề (như tôi đã nói trước đây, chúng tôi sẽ làm như vậy trong các hướng dẫn tiếp theo), chúng tôi đặt biến srt_token thành Sai

Vị trí của tệp âm thanh sau đó được chỉ định (hãy nhớ rằng nó nằm trong thư mục /data của chúng tôi). Tệp âm thanh được sao chép từ đoạn này sang đoạn khác và bản ghi được hiển thị từng phần, với dấu thời gian tương ứng, ngay sau khi hàm phiên mã_non_diarization() được gọi

Sau khi hoàn thành, thư mục chứa tất cả các khối có thể được dọn sạch và văn bản đã hoàn thành được hiển thị

5. Chính

Việc xác định kiến ​​trúc toàn cầu, chính của ứng dụng là tất cả những gì còn lại phải làm

Người dùng có thể chọn sao chép tệp của riêng mình bằng cách nhập tệp đó hoặc tệp bên ngoài bằng cách nhập URL của video bằng cách tạo một st. tiện ích nút radio(). Tùy thuộc vào giá trị của nút radio, chức năng thích hợp (bản ghi từ URL hoặc từ tệp) được khởi chạy

pip install -r requirements.txt
8Chạy ứng dụng của bạn

Trên thực tế, hãy chạy mã của bạn và nhập lệnh sau vào thiết bị đầu cuối của bạn để kiểm tra chương trình của chúng tôi. Một tab trình duyệt internet sẽ mở ra với ứng dụng Streamlit

pip install -r requirements.txt
9

Nếu thao tác với tệp âm thanh trên máy tính lần đầu tiên, bạn có thể gặp lỗi với các thư viện libsndfile, ffprobe và ffmpeg

Đừng lo lắng, cài đặt chúng sẽ nhanh chóng khắc phục những vấn đề này. Lệnh sẽ khác nhau tùy thuộc vào hệ điều hành bạn đang sử dụng. Chẳng hạn, bạn có thể sử dụng apt-get trên Linux

# Models
import torch
from transformers import Wav2Vec2Processor, HubertForCTC

# Audio Manipulation
import audioread
import librosa
from pydub import AudioSegment, silence
import youtube_dl
from youtube_dl import DownloadError

# Others
from datetime import timedelta
import os
import streamlit as st
import time
0

Bạn có thể sử dụng Conda hoặc Miniconda nếu chúng được cài đặt trên hệ điều hành của bạn

# Models
import torch
from transformers import Wav2Vec2Processor, HubertForCTC

# Audio Manipulation
import audioread
import librosa
from pydub import AudioSegment, silence
import youtube_dl
from youtube_dl import DownloadError

# Others
from datetime import timedelta
import os
import streamlit as st
import time
1

Giờ đây, bạn có thể chọn video YouTube hoặc nhập tệp âm thanh của riêng mình vào ứng dụng và nhận bản ghi của video đó nếu ứng dụng khởi chạy mà không gặp trở ngại nào

Rất khó chịu khi tài nguyên địa phương có thể không đủ mạnh để có được bảng điểm chỉ trong vài giây

Sử dụng AI Deploy, bạn có thể nhanh chóng chạy ứng dụng của mình trên GPU. Để làm như vậy, vui lòng tham khảo tài liệu này để khởi động nó

Xem những gì chúng tôi đã tạo trong video dưới đây

Sau khi kết thúc phần hướng dẫn đầu tiên, chúng tôi sẽ trình bày ngắn gọn về ứng dụng Chuyển giọng nói thành văn bản của chúng tôi

Sự kết luận

Giờ đây, bạn có thể nhập tệp âm thanh của riêng mình vào ứng dụng để nhận bản chép lời đầu tiên, điều này thật tuyệt vời

Mặc dù bạn có thể hài lòng với điều đó, nhưng chúng tôi có thể làm tốt hơn thế nữa

Ứng dụng Chuyển giọng nói thành văn bản của chúng tôi vẫn còn rất cơ bản và chúng tôi cần thêm các tính năng mới như khả năng phân biệt giữa những người nói khác nhau, tóm tắt bản chép lời hoặc thêm dấu câu cũng như các tính năng quan trọng khác như khả năng cắt hoặc cắt âm thanh

Chờ bài viết mới nếu bạn muốn cải thiện ứng dụng Streamlit của mình

Tôi là sinh viên ngành kỹ thuật và đã làm việc tại OVHcloud được vài tháng. Tôi quen thuộc với nhiều ngôn ngữ máy tính, nhưng vì tôi tập trung học tập vào trí tuệ nhân tạo nên Python là công cụ chính cho công việc của tôi

Đó là một lĩnh vực đang phát triển cho phép tôi học hỏi và lĩnh hội mọi thứ, để tạo ra nhưng cũng như bạn có thể thấy, để giải thích chúng. )

Ở cuối bài viết đầu tiên này, ứng dụng Chuyển giọng nói thành văn bản của bạn sẽ có thể nhận bản ghi âm thanh và sẽ tạo bản ghi của nó

Mã cuối cùng của ứng dụng có sẵn trong kho lưu trữ GitHub chuyên dụng của chúng tôi

Tổng quan về ứng dụng cuối cùng của chúng tôi

Tập đoàn OVH. Cách xây dựng ứng dụng Speech-To-Text với Python (1/3)

Tổng quan về ứng dụng Speech-To-Text cuối cùng của chúng tôi

Khách quan

Trong các hướng dẫn về sổ ghi chép trước, chúng ta đã thấy cách chuyển lời nói thành văn bản, cách chấm câu trong bản dịch và tóm tắt nó. Chúng tôi cũng đã xem cách phân biệt người nói và cách tạo phụ đề video, đồng thời quản lý các sự cố bộ nhớ tiềm ẩn

Bây giờ chúng ta đã biết cách thực hiện tất cả những điều này, hãy kết hợp tất cả các tính năng này lại với nhau thành một ứng dụng Chuyển giọng nói thành văn bản bằng Python

➡ Để tạo ứng dụng này, chúng tôi sẽ sử dụng Streamlit, một khung Python biến các tập lệnh thành một ứng dụng web có thể chia sẻ. Nếu bạn không biết công cụ này, đừng lo lắng, nó rất đơn giản để sử dụng

Bài viết này được tổ chức như sau

  • Nhập mã từ các hướng dẫn trước
  • Viết ứng dụng Streamlit
  • Chạy ứng dụng của bạn

Trong các bài viết tiếp theo, chúng ta sẽ xem cách triển khai các tính năng nâng cao hơn (ghi nhật ký, tóm tắt, chấm câu,…) và chúng ta cũng sẽ tìm hiểu cách xây dựng và sử dụng hình ảnh Docker tùy chỉnh cho ứng dụng Streamlit, cho phép chúng ta triển khai

⚠️ Vì bài viết này sử dụng mã đã được giải thích trong các hướng dẫn sổ tay trước nên chúng tôi sẽ không giải thích lại tính hữu ích của nó tại đây. Do đó, chúng tôi khuyên bạn nên đọc sổ ghi chép trước

Nhập mã từ các hướng dẫn trước

1. Thiết lập môi trường

Để bắt đầu, hãy tạo môi trường Python của chúng ta. Để thực hiện việc này, hãy tạo một tệp có tên yêu cầu. txt và thêm văn bản sau vào nó. Điều này sẽ cho phép chúng tôi chỉ định từng phiên bản của thư viện theo yêu cầu của dự án Bài phát biểu thành văn bản của chúng tôi

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
3

Sau đó, bạn có thể cài đặt tất cả các thành phần này chỉ trong một lệnh. Để làm như vậy, bạn chỉ cần mở một thiết bị đầu cuối và nhập lệnh sau

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
4

2. Nhập thư viện

Khi môi trường của bạn đã sẵn sàng, hãy tạo một tệp có tên ứng dụng. py và nhập các thư viện cần thiết mà chúng tôi đã sử dụng trong sổ ghi chép

Chúng sẽ cho phép chúng ta sử dụng các mô hình trí tuệ nhân tạo, để thao tác với các tệp âm thanh, thời gian,…

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
5

3. Chức năng

Chúng tôi cũng cần sử dụng một số chức năng trước đây, có thể bạn sẽ nhận ra một số trong số chúng

⚠️ Nhắc nhở. Tất cả mã này đã được giải thích trong sổ tay hướng dẫn. Đó là lý do tại sao chúng tôi sẽ không giải thích lại tính hữu ích của nó ở đây

Để bắt đầu, hãy tạo chức năng cho phép bạn phiên âm một đoạn âm thanh

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
6

Sau đó, tạo bốn chức năng cho phép phương pháp phát hiện im lặng, mà chúng tôi đã giải thích trong hướng dẫn sổ ghi chép đầu tiên

Nhận dấu thời gian của sự im lặng

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
7

Lấy giá trị trung bình của mỗi dấu thời gian

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
8

Tạo một phân phối thông thường, hợp nhất các dấu thời gian theo giá trị min_space và max_space

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
9

Thêm "thời gian cắt" tự động vào danh sách im lặng cho đến khi giá trị kết thúc tùy thuộc vào giá trị min_space và max_space

def detect_silences(audio):

    # Get Decibels (dB) so silences detection depends on the audio instead of a fixed value
    dbfs = audio.dBFS

    # Get silences timestamps > 750ms
    silence_list = silence.detect_silence(audio, min_silence_len=750, silence_thresh=dbfs-14)

    return silence_list
0

Tạo một chức năng để dọn dẹp thư mục nơi chúng tôi lưu âm thanh và đoạn âm thanh, để chúng tôi không giữ chúng sau khi phiên âm

def detect_silences(audio):

    # Get Decibels (dB) so silences detection depends on the audio instead of a fixed value
    dbfs = audio.dBFS

    # Get silences timestamps > 750ms
    silence_list = silence.detect_silence(audio, min_silence_len=750, silence_thresh=dbfs-14)

    return silence_list
1

Viết mã ứng dụng Streamlit

1. Cấu hình của ứng dụng

Bây giờ chúng ta đã có những điều cơ bản, chúng ta có thể tạo chức năng cho phép định cấu hình ứng dụng. Nó sẽ đặt tiêu đề và biểu tượng cho ứng dụng của chúng ta, đồng thời sẽ tạo một thư mục dữ liệu để ứng dụng có thể lưu trữ các tệp âm thanh trong đó. Đây là chức năng

def detect_silences(audio):

    # Get Decibels (dB) so silences detection depends on the audio instead of a fixed value
    dbfs = audio.dBFS

    # Get silences timestamps > 750ms
    silence_list = silence.detect_silence(audio, min_silence_len=750, silence_thresh=dbfs-14)

    return silence_list
2

Như bạn có thể thấy, thư mục dữ liệu này nằm ở thư mục gốc của thư mục mẹ (được biểu thị bằng. / ký hiệu). Nó sẽ chỉ được tạo nếu ứng dụng được khởi chạy cục bộ trên máy tính của bạn, vì AI Deploy đã tạo sẵn thư mục này

➡️ Chúng tôi khuyên bạn không nên thay đổi vị trí của thư mục dữ liệu (. /). Thật vậy, vị trí này giúp bạn dễ dàng sắp xếp giữa việc chạy ứng dụng cục bộ hoặc trên AI Deploy

2. Tải bài phát biểu vào mô hình văn bản

Tạo hàm cho phép nạp lời nói vào mô hình văn bản

Khi chúng tôi bắt đầu, chúng tôi chỉ nhập mô hình sao chép vào lúc này. Các tính năng khác chúng tôi sẽ triển khai ở bài viết sau 😉

⚠️ Ở đây, trường hợp sử dụng là nhận dạng giọng nói tiếng Anh, nhưng bạn có thể thực hiện bằng ngôn ngữ khác nhờ một trong nhiều mẫu có sẵn trên trang web Ôm mặt. Trong trường hợp này, hãy nhớ rằng bạn sẽ không thể kết hợp nó với một số mô hình mà chúng tôi sẽ sử dụng trong bài viết tiếp theo, vì một số mô hình chỉ hoạt động trên bảng điểm tiếng Anh

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
40

Chúng tôi sử dụng @st. bộ đệm (allow_output_mutation=True) tại đây. Điều này yêu cầu Streamlit chạy chức năng và lưu trữ kết quả trong bộ đệm cục bộ, vì vậy, lần sau khi chúng tôi gọi chức năng (làm mới ứng dụng), Streamlit biết rằng nó có thể bỏ qua việc thực thi chức năng này. Thật vậy, vì chúng tôi đã nhập (các) mô hình một lần (khởi tạo ứng dụng), chúng tôi không được lãng phí thời gian để tải lại chúng mỗi khi chúng tôi muốn sao chép một tệp mới

Tuy nhiên, việc tải xuống mô hình khi khởi chạy ứng dụng cần có thời gian vì nó phụ thuộc vào một số yếu tố như kết nối Internet của chúng tôi. Đối với một dòng máy, đây không phải là vấn đề vì thời gian tải xuống vẫn khá nhanh. Nhưng với tất cả các dòng máy mà chúng tôi định nạp trong bài viết tiếp theo, thời gian khởi tạo này có thể sẽ lâu hơn, điều này sẽ gây khó chịu 😪

➡️ Đó là lý do tại sao chúng tôi sẽ đề xuất cách giải quyết vấn đề này trong một bài đăng tiếp theo trên blog

3. Nhận tệp âm thanh

Khi chúng tôi đã tải mô hình, chúng tôi cần một tệp âm thanh để sử dụng nó 🎵

Đối với điều này, chúng tôi sẽ nhận ra hai tính năng. Cái đầu tiên sẽ cho phép người dùng nhập tệp âm thanh của riêng mình. Cái thứ hai sẽ cho phép anh ta chỉ ra một URL video mà anh ta muốn lấy bản ghi

3. 1. Cho phép người dùng tải lên tệp (mp3/mp4/wav)

Cho phép người dùng tải lên tệp âm thanh của riêng mình nhờ một st. tiện ích file_uploader()

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
41

Như bạn có thể thấy, nếu biến uploaded_file không phải là None, có nghĩa là người dùng đã tải lên một tệp âm thanh, chúng tôi sẽ khởi chạy quá trình phiên âm bằng cách gọi hàm phiên mã () mà chúng tôi sẽ tạo ngay sau đây

3. 2. Phiên âm video từ YouTube

Tạo chức năng cho phép tải xuống âm thanh từ liên kết YouTube hợp lệ

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
42

⚠️ Nếu bạn không phải là quản trị viên máy tính của mình, chức năng này có thể không hoạt động để thực thi cục bộ

Sau đó, chúng ta cần hiển thị một phần tử cho phép người dùng chỉ ra URL mà họ muốn phiên âm

Chúng ta có thể làm điều đó nhờ st. tiện ích text_input(). Người dùng sẽ có thể nhập URL của video mà anh ấy quan tâm. Sau đó, chúng tôi xác minh nhanh. nếu liên kết đã nhập có vẻ chính xác (chứa mẫu liên kết YouTube. “youtube”), chúng tôi cố gắng trích xuất âm thanh từ video URL rồi phiên âm âm thanh đó

Đây là chức năng sau

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
43

4. Phiên âm tập tin âm thanh

Bây giờ, chúng ta phải viết các hàm liên kết phần lớn những hàm mà chúng ta đã xác định

Để bắt đầu, chúng ta viết mã của hàm init_transcription(). Nó thông báo cho người dùng rằng quá trình phiên âm của tệp âm thanh đang bắt đầu và nó sẽ phiên âm âm thanh từ giây bắt đầu đến giây kết thúc. Hiện tại, các giá trị này tương ứng với các đầu thời gian của âm thanh (0 giây và độ dài âm thanh). Vì vậy, nó không thực sự thú vị, nhưng nó sẽ hữu ích trong tập tiếp theo 😌

Hàm này cũng khởi tạo một số biến. Trong số đó, srt_text và save_results là các biến mà chúng ta cũng sẽ sử dụng trong bài viết sau. Đừng lo lắng về họ bây giờ

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
44

Chúng tôi có các chức năng thực hiện phương pháp phát hiện im lặng và phiên âm tệp âm thanh. Nhưng bây giờ chúng ta cần liên kết tất cả các chức năng này. Chức năng phiên mã_non_diarization() sẽ làm điều đó cho chúng tôi

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
45

Bạn sẽ nhận thấy rằng hàm này gọi hàm display_transcription(), hàm này hiển thị đúng phần tử theo tham số do người dùng chọn

Hiện tại, hiển thị là cơ bản vì chúng tôi chưa thêm thông số của người dùng. Đây là lý do tại sao chúng tôi sẽ sửa đổi chức năng này trong bài viết tiếp theo, để có thể xử lý các trường hợp hiển thị khác nhau, tùy thuộc vào tham số đã chọn

Bạn có thể thêm nó vào ứng dụng của mình. tập tin py

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
46

Khi điều này được thực hiện, tất cả những gì bạn phải làm là hiển thị tất cả các phần tử và liên kết chúng bằng hàm phiên mã ()

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
47

Chức năng khổng lồ này trông giống như mã khối chính của chúng tôi. Nó gần như tập hợp tất cả các chức năng đã triển khai

Trước hết, nó truy xuất độ dài của tệp âm thanh và cho phép người dùng phát tệp đó với. audio(), một tiện ích hiển thị trình phát âm thanh. Sau đó, nếu độ dài âm thanh lớn hơn 0 giây và người dùng nhấp vào nút “Phiên âm”, quá trình sao chép sẽ được khởi chạy

Người dùng biết rằng mã đang chạy vì tất cả tập lệnh được đặt ở vị trí cố định. spinner(), được hiển thị dưới dạng một spinner tải trên ứng dụng

Trong mã này, chúng tôi khởi tạo một số biến. Hiện tại, chúng tôi đặt srt_token thành Sai, vì chúng tôi sẽ không tạo phụ đề (chúng tôi sẽ làm điều đó trong các hướng dẫn tiếp theo như tôi đã đề cập)

Sau đó, vị trí của tệp âm thanh được chỉ định (hãy nhớ rằng nó nằm trong. /Thư mục dữ liệu). Quá trình phiên mã tại thời điểm đó thực sự bắt đầu khi chức năng phiên mã_non_diarization() được gọi. Tệp âm thanh được sao chép từ đoạn này sang đoạn khác và bản ghi được hiển thị từng phần với dấu thời gian tương ứng

Sau khi hoàn tất, chúng ta có thể dọn dẹp thư mục chứa tất cả các khối và văn bản cuối cùng được hiển thị

5. Chính

Tất cả những gì còn lại là xác định kiến ​​trúc toàn cầu, chính của ứng dụng của chúng ta

Chúng ta chỉ cần tạo một st. tiện ích nút radio() để người dùng có thể chọn phiên âm tệp của chính mình bằng cách nhập tệp đó hoặc tệp bên ngoài bằng cách nhập URL của video. Tùy thuộc vào giá trị nút radio, chúng tôi khởi chạy đúng chức năng (bản ghi từ URL hoặc từ tệp)

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
48

Chạy ứng dụng của bạn

Chúng tôi đã có thể thử chương trình của chúng tôi. Thật vậy, hãy chạy mã của bạn và nhập lệnh sau vào thiết bị đầu cuối của bạn. Ứng dụng Streamlit sẽ mở trong một tab của trình duyệt của bạn

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
49

⚠️⚠️ Nếu đây là lần đầu tiên bạn thao tác với các tệp âm thanh trên máy tính của mình, bạn có thể gặp một số Lỗi OS về thư viện libsndfile, ffprobe và ffmpeg

Đừng lo, bạn có thể dễ dàng khắc phục những lỗi này bằng cách cài đặt chúng. Lệnh sẽ khác nhau tùy thuộc vào hệ điều hành bạn đang sử dụng. Ví dụ: trên Linux, bạn có thể sử dụng apt-get

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
50

Nếu bạn đã cài đặt Conda hoặc Miniconda trên HĐH của mình, bạn có thể sử dụng

def transcribe_audio_part(filename, stt_model, stt_tokenizer, myaudio, sub_start, sub_end, index):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    try:
        with torch.no_grad():
            new_audio = myaudio[sub_start:sub_end]  # Works in milliseconds
            path = filename[:-3] + "audio_" + str(index) + ".mp3"
            new_audio.export(path)  # Exports to a mp3 file in the current path

            # Load audio file with librosa, set sound rate to 16000 Hz because the model we use was trained on 16000 Hz data
            input_audio, _ = librosa.load(path, sr=16000)

            # return PyTorch torch.Tensor instead of a list of python integers thanks to return_tensors = 'pt'
            input_values = stt_tokenizer(input_audio, return_tensors="pt").to(device).input_values

            # Get logits from the data structure containing all the information returned by the model and get our prediction
            logits = stt_model.to(device)(input_values).logits
            prediction = torch.argmax(logits, dim=-1)
           
            # Decode & lower our string (model's output is only uppercase)
            if isinstance(stt_tokenizer, Wav2Vec2Tokenizer):
                transcription = stt_tokenizer.batch_decode(prediction)[0]
            elif isinstance(stt_tokenizer, Wav2Vec2Processor):
                transcription = stt_tokenizer.decode(prediction[0])

            # return transcription
            return transcription.lower()

    except audioread.NoBackendError:
        # Means we have a chunk with a [value1 : value2] case with value1>value2
        st.error("Sorry, seems we have a problem on our side. Please change start & end values.")
        time.sleep(3)
        st.stop()
51

Nếu ứng dụng khởi chạy mà không có lỗi, xin chúc mừng 👏. Giờ đây, bạn có thể chọn video YouTube hoặc nhập tệp âm thanh của riêng mình vào ứng dụng và nhận bản ghi của video đó

😪 Thật không may, tài nguyên cục bộ có thể không đủ mạnh để có được bản ghi chỉ trong vài giây, điều này khá khó chịu

➡️ Để tiết kiệm thời gian, bạn có thể chạy ứng dụng của mình trên GPU nhờ AI Deploy. Để làm điều này, vui lòng tham khảo tài liệu này để khởi động nó

Bạn có thể thấy những gì chúng tôi đã xây dựng trên video sau

Trình diễn nhanh ứng dụng Chuyển giọng nói thành văn bản của chúng tôi sau khi hoàn thành hướng dẫn đầu tiên này

Sự kết luận

Làm tốt lắm 🥳. Giờ đây, bạn có thể nhập tệp âm thanh của riêng mình trên ứng dụng và nhận bản chép lời đầu tiên của mình

Bạn có thể hài lòng với điều đó, nhưng chúng tôi có thể làm tốt hơn thế nữa

Thật vậy, ứng dụng Speech-To-Text của chúng tôi vẫn còn rất cơ bản. Chúng tôi cần triển khai các chức năng mới như phân biệt người nói, tóm tắt bản ghi hoặc dấu chấm câu cũng như các chức năng thiết yếu khác như khả năng cắt/cắt âm thanh, tải xuống bản ghi, tương tác với dấu thời gian, chứng minh văn bản, …

➡️ Nếu bạn muốn cải thiện ứng dụng Streamlit của mình, hãy chờ bài viết mới 😉

Tập đoàn OVH. Cách xây dựng ứng dụng Speech-To-Text với Python (1/3)

Mathieu Busquet

+ bài viết

Tôi là sinh viên kỹ thuật đã làm việc tại OVHcloud được vài tháng. Tôi quen thuộc với một số ngôn ngữ máy tính, nhưng trong ngành học của mình, tôi chuyên về trí tuệ nhân tạo và do đó Python là công cụ làm việc chính của tôi

Đó là một lĩnh vực đang phát triển cho phép tôi khám phá và hiểu mọi thứ, để tạo ra nhưng cũng như bạn thấy để giải thích chúng. )