Spaces:
Sleeping
Sleeping
| import torch | |
| import os | |
| import shutil | |
| import whisper | |
| import uuid | |
| from itertools import product | |
| from fastapi import FastAPI, UploadFile, File | |
| from pydantic import BaseModel | |
| from typing import List | |
| from transformers import AutoTokenizer, AutoModelForMaskedLM | |
| app = FastAPI() | |
| # --- 1. 讟注讬谞转 讛诪讜讚诇讬诐 (讬讬讟注谞讜 驻注诐 讗讞转 讻砖讛砖专转 注讜诇讛) --- | |
| print("Loading DictaBERT model...") | |
| model_path = "dicta-il/dictabert" | |
| tokenizer = AutoTokenizer.from_pretrained(model_path) | |
| bert_model = AutoModelForMaskedLM.from_pretrained(model_path) | |
| bert_model.eval() | |
| print("Loading Whisper model (this might take a minute)...") | |
| # 讟讜注谞讬诐 讗转 讛诪讜讚诇 讛讙讚讜诇. 讛砖专转 讛讞讬谞诪讬 讛讜讗 CPU, 讗讝 讛讜讗 讬专讜抓 注诇讬讜. | |
| whisper_model = whisper.load_model("large-v2") | |
| print("Models loaded successfully!") | |
| # --- 2. 诪讘谞讬 谞转讜谞讬诐 --- | |
| class PredictionRequest(BaseModel): | |
| template: str | |
| lists: List[List[str]] | |
| # --- 3. 诇讜讙讬拽讛 --- | |
| def get_top_k_combinations(template, lists_of_candidates, k=3): | |
| num_masks = len(lists_of_candidates) | |
| text = template | |
| for i in range(1, num_masks + 1): | |
| text = text.replace(f"{{m{i}}}", tokenizer.mask_token) | |
| inputs = tokenizer(text, return_tensors="pt") | |
| mask_indices = torch.where(inputs["input_ids"] == tokenizer.mask_token_id)[1] | |
| with torch.no_grad(): | |
| outputs = bert_model(**inputs) | |
| logits = outputs.logits | |
| all_combinations_with_scores = [] | |
| for combination in product(*lists_of_candidates): | |
| current_combined_score = 0 | |
| for i, word in enumerate(combination): | |
| word_id = tokenizer.convert_tokens_to_ids(word) | |
| current_combined_score += logits[0, mask_indices[i], word_id].item() | |
| all_combinations_with_scores.append((combination, current_combined_score)) | |
| return sorted(all_combinations_with_scores, key=lambda x: x[1], reverse=True)[:k] | |
| def format_final_sentence(template, best_comb): | |
| sentence = template | |
| for i, word in enumerate(best_comb): | |
| target = "{m" + str(i + 1) + "}" | |
| sentence = sentence.replace(target, word) | |
| return sentence | |
| # --- 4. 谞转讬讘讬 API --- | |
| def home(): | |
| return {"message": "Speechly API is running!"} | |
| async def predict(data: PredictionRequest): | |
| top_combinations = get_top_k_combinations(data.template, data.lists, k=3) | |
| final_sentences = [format_final_sentence(data.template, c[0]) for c in top_combinations] | |
| top_words = [list(c[0]) for c in top_combinations] | |
| return {"full_sentences": final_sentences, "mask_selections": top_words} | |
| def transcribe(file: UploadFile = File(...)): | |
| temp_path = f"temp_{uuid.uuid4()}_{file.filename}" | |
| try: | |
| with open(temp_path, "wb") as buffer: | |
| shutil.copyfileobj(file.file, buffer) | |
| result = whisper_model.transcribe( | |
| temp_path, | |
| language="he", | |
| temperature=0, | |
| fp16=False, # 讗谞讞谞讜 注诇 CPU 讗讝 讝讛 讞讜讘讛 诇讛讬讜转 False | |
| verbose=False, | |
| condition_on_previous_text=False | |
| ) | |
| return {"status": "success", "transcription": result["text"].strip()} | |
| except Exception as e: | |
| return {"status": "error", "message": str(e)} | |
| finally: | |
| if os.path.exists(temp_path): | |
| os.remove(temp_path) |