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ó Show 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ôiTổng quan về chương trình Speech-To-Text gần đây nhất của chúng tôi Khách quanChú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
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ườngTạ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 _10Sau đó, 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ệnTạ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 time3. 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 _15Tạ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 _16tù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 _17Tạ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 StreamlitChứ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 _19Như 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ảnTạ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 thanhKhi 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 WAVmộ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.txt1 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 YouTubeTạ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 haiTí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.txt34. 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.txt4 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.txt5 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.txt6 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.txt7 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ínhViệ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.txt8Chạ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.txt9 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 time0 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 time1 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ậnGiờ đâ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ôiTổng quan về ứng dụng Speech-To-Text cuối cùng của chúng tôi Khách quanTrong 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
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ước1. 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ệnKhi 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ăngChú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_list0 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_list1 Viết mã ứng dụng Streamlit1. Cấu hình của ứng dụngBâ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_list2 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ảnTạ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 thanhKhi 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ừ YouTubeTạ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 thanhBâ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ínhTấ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ạnChú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ậnLà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 😉 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. ) |