как скрыть сообщенния

 The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...
To disable this warning, you can either:
        - Avoid using `tokenizers` before the fork if possible
        - Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)
huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...
To disable this warning, you can either:
        - Avoid using `tokenizers` before the fork if possible
        - Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)
left_result Давай, Слушай, слушай.


вот мой скрипт
import os
import requests
import time
import json
import numpy as np
import torch
import soundfile as sf
import librosa
from pydub import AudioSegment

import kaldi_native_fbank as knf
import onnxruntime as ort

from sbert_punc_case_ru import SbertPuncCase


from flask import Flask, request, jsonify
import threading


# --- сюда вставляем класс OnnxModel и все функции create_fbank и compute_features ---

def create_fbank():
    opts = knf.FbankOptions()
    opts.frame_opts.dither = 0
    opts.frame_opts.remove_dc_offset = False
    opts.frame_opts.preemph_coeff = 0
    opts.frame_opts.window_type = "hann"
    opts.frame_opts.round_to_power_of_two = False
    opts.mel_opts.low_freq = 0
    opts.mel_opts.high_freq = 4000 # половина частоты дискретизации (Nyquist freq)
    opts.mel_opts.num_bins = 64
    fbank = knf.OnlineFbank(opts)
    return fbank

def compute_features(audio, fbank):
    assert len(audio.shape) == 1, audio.shape
    #fbank.accept_waveform(16000, audio)
    fbank.accept_waveform(8000, audio)    # 8000 Hz, не 16000
    ans = []
    processed = 0
    while processed < fbank.num_frames_ready:
        ans.append(np.array(fbank.get_frame(processed)))
        processed += 1
    ans = np.stack(ans)
    return ans

class OnnxModel:
    def __init__(self, encoder: str, decoder: str, joiner: str):
        self.init_encoder(encoder)
        self.init_decoder(decoder)
        self.init_joiner(joiner)

    def init_encoder(self, encoder):
        session_opts = ort.SessionOptions()
        session_opts.inter_op_num_threads = 6
        session_opts.intra_op_num_threads = 6
        self.encoder = ort.InferenceSession(
            encoder,
            sess_options=session_opts,
            providers=["CPUExecutionProvider"],
        )
        meta = self.encoder.get_modelmeta().custom_metadata_map
        self.normalize_type = meta.get("normalize_type", "")
        self.pred_rnn_layers = int(meta.get("pred_rnn_layers", "1"))
        self.pred_hidden = int(meta.get("pred_hidden", "320"))

    def init_decoder(self, decoder):
        session_opts = ort.SessionOptions()
        session_opts.inter_op_num_threads = 6
        session_opts.intra_op_num_threads = 6
        self.decoder = ort.InferenceSession(
            decoder,
            sess_options=session_opts,
            providers=["CPUExecutionProvider"],
        )

    def init_joiner(self, joiner):
        session_opts = ort.SessionOptions()
        session_opts.inter_op_num_threads = 6
        session_opts.intra_op_num_threads = 6
        self.joiner = ort.InferenceSession(
            joiner,
            sess_options=session_opts,
            providers=["CPUExecutionProvider"],
        )

    def get_decoder_state(self):
        batch_size = 1
        state0 = torch.zeros(self.pred_rnn_layers, batch_size, self.pred_hidden).numpy()
        state1 = torch.zeros(self.pred_rnn_layers, batch_size, self.pred_hidden).numpy()
        return state0, state1

    def run_encoder(self, x: np.ndarray):
        x = torch.from_numpy(x)
        x = x.t().unsqueeze(0)  # Shape: [1, C, T]
        x_lens = torch.tensor([x.shape[-1]], dtype=torch.int64)

        (encoder_out, out_len) = self.encoder.run(
            [
                self.encoder.get_outputs()[0].name,
                self.encoder.get_outputs()[1].name,
            ],
            {
                self.encoder.get_inputs()[0].name: x.numpy(),
                self.encoder.get_inputs()[1].name: x_lens.numpy(),
            },
        )
        return encoder_out

    def run_decoder(self, token: int, state0: np.ndarray, state1: np.ndarray):
        target = torch.tensor([[token]], dtype=torch.int32).numpy()
        target_len = torch.tensor([1], dtype=torch.int32).numpy()

        (decoder_out, decoder_out_length, state0_next, state1_next,) = self.decoder.run(
            [
                self.decoder.get_outputs()[0].name,
                self.decoder.get_outputs()[1].name,
                self.decoder.get_outputs()[2].name,
                self.decoder.get_outputs()[3].name,
            ],
            {
                self.decoder.get_inputs()[0].name: target,
                self.decoder.get_inputs()[1].name: target_len,
                self.decoder.get_inputs()[2].name: state0,
                self.decoder.get_inputs()[3].name: state1,
            },
        )
        return decoder_out, state0_next, state1_next

    def run_joiner(self, encoder_out: np.ndarray, decoder_out: np.ndarray):
        logit = self.joiner.run(
            [
                self.joiner.get_outputs()[0].name,
            ],
            {
                self.joiner.get_inputs()[0].name: encoder_out,
                self.joiner.get_inputs()[1].name: decoder_out,
            },
        )[0]
        return logit


def load_tokens(tokens_path="./tokens.txt"):
    id2token = dict()
    with open(tokens_path, encoding="utf-8") as f:
        for line in f:
            fields = line.strip().split()
            if len(fields) == 1:
                id2token[int(fields[0])] = " "
            else:
                t, idx = fields
                id2token[int(idx)] = t
    return id2token


# новая функция вместо transcribe_audio_to_json с новой оннх моделью
def transcribe_audio_to_json_onnx(model: OnnxModel, audio_file_path, id2token):
    # Здесь мы рассматриваем только одноканальное аудио (модель рассчитана на 1 канал)
    # Загружаем аудио (pydub можно убрать, тк мы работаем с numpy через soundfile)
    audio, sr = sf.read(audio_file_path, dtype="float32")
    if len(audio.shape) > 1:
        # если стерео, берём первый канал
        audio = audio[:, 0]
    if sr != 16000:
        audio = librosa.resample(audio, orig_sr=sr, target_sr=16000)
        sr = 16000

    # добавим padding 2 секунды тишины в конец
    tail_padding = np.zeros(sr * 2, dtype=np.float32)
    audio = np.concatenate([audio, tail_padding])

    fbank = create_fbank()
    features = compute_features(audio, fbank)

    blank = len(id2token) - 1
    ans = [blank]  # список индексов токенов
    state0, state1 = model.get_decoder_state()
    decoder_out, state0_next, state1_next = model.run_decoder(ans[-1], state0, state1)

    encoder_out = model.run_encoder(features)

    # decode loop
    for t in range(encoder_out.shape[2]):
        encoder_out_t = encoder_out[:, :, t : t + 1]
        logits = model.run_joiner(encoder_out_t, decoder_out)
        logits = torch.from_numpy(logits).squeeze()
        idx = torch.argmax(logits, dim=-1).item()
        if idx != blank:
            ans.append(idx)
            state0 = state0_next
            state1 = state1_next
            decoder_out, state0_next, state1_next = model.run_decoder(ans[-1], state0, state1)

    ans = ans[1:]  # удаляем первый blank токен

    tokens = [id2token.get(i, "") for i in ans]
    underline = "▁"
    text = "".join(tokens).replace(underline, " ").strip()

    # Вернём один "сегмент" с примерным временем от 0 до длины аудио в секундах
    audio_duration = len(audio) / sr

    result = [{
        "channel": "mono",
        "start": 0.0,
        "end": audio_duration,
        "text": text
    }]

    return result
   
def transcribe_channel_by_chunks(model: OnnxModel, audio_segment: AudioSegment, id2token, chunk_ms=60000):
    """
    Нарезаем audio_segment на куски chunk_ms мс (например, 1 минута = 60000 мс),
    транскрибируем каждый кусок, склеиваем результаты в один текст.
    """
    total_len = len(audio_segment)
    texts = []

    for start_ms in range(0, total_len, chunk_ms):
        end_ms = min(start_ms + chunk_ms, total_len)
        chunk = audio_segment[start_ms:end_ms]

        temp_file = f"temp_chunk_{start_ms}_{end_ms}.wav"
        chunk.export(temp_file, format="wav")

        res = transcribe_audio_to_json_onnx(model, temp_file, id2token)
        os.remove(temp_file)

        if res and len(res) > 0:
            text = res[0]["text"].strip()
            texts.append(text)

    full_text = " ".join(texts).strip()
    return full_text


def transcribe_stereo_onnx_by_chunks(model: OnnxModel, audio_file_path: str, id2token):
    audio = AudioSegment.from_file(audio_file_path)
    channels = audio.split_to_mono()
    
    if len(channels) == 0:
        # Почему-то нет каналов - вернуть пустые списки или исключение
        return [], []
    elif len(channels) == 1:
        # Если канал один, обрабатываем только его (левый, например)
        left_text = transcribe_channel_by_chunks(model, channels[0], id2token)
        return [{"channel": "left", "start": 0.0, "end": len(channels[0]) / 1000, "text": left_text}], []
    else:
        # Два и более канала, берем первые два
        left_text = transcribe_channel_by_chunks(model, channels[0], id2token)
        right_text = transcribe_channel_by_chunks(model, channels[1], id2token)

        left_result = [{
            "channel": "left",
            "start": 0.0,
            "end": len(channels[0]) / 1000,
            "text": left_text
        }]

        right_result = [{
            "channel": "right",
            "start": 0.0,
            "end": len(channels[1]) / 1000,
            "text": right_text
        }]

        return left_result, right_result
     
def transcribe_stereo_onnx_by_chunks22(model: OnnxModel, audio_file_path: str, id2token):
    audio = AudioSegment.from_file(audio_file_path)
    channels = audio.split_to_mono()

    left_text = transcribe_channel_by_chunks(model, channels[0], id2token)
    right_text = transcribe_channel_by_chunks(model, channels[1], id2token)

    left_result = [{
        "channel": "left",
        "start": 0.0,
        "end": len(channels[0]) / 1000,
        "text": left_text
    }]

    right_result = [{
        "channel": "right",
        "start": 0.0,
        "end": len(channels[1]) / 1000,
        "text": right_text
    }]

    return left_result, right_result
    
# Обновленная функция обработки и разделения каналов
def transcribe_stereo_onnx(model: OnnxModel, audio_file_path, id2token):
    audio = AudioSegment.from_file(audio_file_path)
    channels = audio.split_to_mono()

    results_left = []
    results_right = []

    for i, channel in enumerate(channels):
        temp_path = f"temp_channel_{i + 1}.wav"
        channel.export(temp_path, format="wav")
        res = transcribe_audio_to_json_onnx(model, temp_path, id2token)

        # уточняем channel-метку
        for r in res:
            r["channel"] = "left" if i == 0 else "right"

        if i == 0:
            results_left.extend(res)
        else:
            results_right.extend(res)

        # Можно удалить временный файл
        os.remove(temp_path)

    # Добавляем id
    for idx, item in enumerate(results_left):
        item["id"] = idx + 1
    for idx, item in enumerate(results_right):
        item["id"] = idx + 1

    return results_left, results_right

# Ниже оставляем вспомогательные функции download_audio, get_json_from_url, trim_file_path без изменений


app = Flask(__name__)

# предполагается, что ниже уже есть весь ваш код с OnnxModel, transcribe_stereo_onnx_by_chunks и т.д.
# инициализируем модель и tokens при старте
path_model = "/home/user/call_record/sber/transducer-giga"

encoder_path = f"{path_model}/encoder.int8.onnx"
decoder_path = f"{path_model}/decoder.onnx"
joiner_path = f"{path_model}/joiner.onnx"
tokens_path = f"{path_model}/tokens.txt"

model_onnx = OnnxModel(encoder_path, decoder_path, joiner_path)
id2token = load_tokens(tokens_path)

pymodel = SbertPuncCase()



@app.route('/transcribe', methods=['POST'])
def transcribe():
    data = request.json
    if not data or 'audio_path' not in data:
        return jsonify({"error": "audio_path not provided"}), 400
    
    audio_path = data["audio_path"]
    
    print(f"{audio_path}")
    try:
        left_result, right_result = transcribe_stereo_onnx_by_chunks(model_onnx, audio_path, id2token)
        
        # Пунктуация текста для левого канала
        if left_result and len(left_result) > 0 and left_result[0].get('text'):
            left_result[0]['text'] = pymodel.punctuate(left_result[0]['text'])
        else:
            print("Left channel text missing or empty")

        # Пунктуация текста для правого канала
        if right_result and len(right_result) > 0 and right_result[0].get('text'):
            right_result[0]['text'] = pymodel.punctuate(right_result[0]['text'])
        else:
            print("Right channel text missing or empty")
   
        print(f"left_result {left_result[0]['text']}")
        print(f"right_result {right_result[0]['text']}")
        # Возвращаем JSON с результатами
        return jsonify({
            "left": left_result[0]['text'],
            "right": right_result[0]['text']
        })
        
    except Exception as e:
        return jsonify({"error": str(e)}), 500


def run_server():
    app.run(host="0.0.0.0", port=5002)

if __name__ == "__main__":
    run_server()