Uotpia commited on
Commit
60c0e7e
·
verified ·
1 Parent(s): e8d5270

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -22
app.py CHANGED
@@ -8,31 +8,37 @@ from fastapi import FastAPI, UploadFile, File, Form, HTTPException
8
  from fastapi.responses import JSONResponse, PlainTextResponse
9
  from transformers import pipeline
10
 
11
- # 1. 加载模型(为了让你随时可用且不限额度,此处先使用 CPU 演示;
12
- # 如需切换回 GPU,请取消 transcribe_core 上的 @spaces.GPU 注释,并将 device 改为 "cuda")
13
  MODEL_NAME = "openai/whisper-small"
 
 
14
  pipe = pipeline(
15
  "automatic-speech-recognition",
16
  model=MODEL_NAME,
17
  chunk_length_s=30,
18
- device="cpu" # 若要 GPU 极速,修改为 "cuda"
19
  )
20
 
21
- # 2. 核心转录逻辑
22
- # @spaces.GPU # 如果你想要在 GPU 额度内极速转录,请取消这一行的注释
23
  def transcribe_core(audio_path: str, target_language: str = None, is_translate: bool = False):
24
- generate_kwargs = {}
 
25
 
26
- # 支持指定语言,如果不指定,让模型自动检测
27
  if target_language:
28
  generate_kwargs["language"] = target_language
29
 
30
- # 如果是翻译任务(translations 端点),强制指定任务和输出语言为英文
31
  if is_translate:
32
  generate_kwargs["language"] = "english"
33
  generate_kwargs["task"] = "translate"
34
 
35
- result = pipe(audio_path, generate_kwargs=generate_kwargs)
 
 
 
 
 
36
  return result["text"]
37
 
38
  # --- Gradio 界面 ---
@@ -54,16 +60,14 @@ demo = gr.Interface(
54
 
55
  app = demo.app
56
 
57
- # --- 🛠️ 核心部分:完美兼容 OpenAI 的处理函数 ---
58
  async def process_openai_audio_request(file, response_format, language, is_translate):
59
- # 限制并确保支持的文件后缀,避免 tempfile 出错
60
  suffix = os.path.splitext(file.filename)[1] or ".mp3"
61
  with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file:
62
  shutil.copyfileobj(file.file, temp_file)
63
  temp_path = temp_file.name
64
 
65
  try:
66
- # 执行转录
67
  text = transcribe_core(temp_path, target_language=language, is_translate=is_translate)
68
  except Exception as e:
69
  raise HTTPException(status_code=500, detail=f"OpenAI Audio API failed: {str(e)}")
@@ -71,24 +75,21 @@ async def process_openai_audio_request(file, response_format, language, is_trans
71
  if os.path.exists(temp_path):
72
  os.remove(temp_path)
73
 
74
- # 100% 兼容 OpenAI 的输出格式逻辑 (支持 json, text, verbose_json 等格式)
75
  if response_format in ["text", "vtt", "srt"]:
76
  return PlainTextResponse(text)
77
 
78
- # 如果是 json 或默认情况,返回标准的 OpenAI 字典
79
- # verbose_json 在 Whisper pipeline 简化版中,我们也提供标准兼容层
80
  return JSONResponse(content={"text": text})
81
 
82
 
83
- # 3. 🎯 完美兼容接口一:语音转录 (Transcriptions)
84
  @app.post("/v1/audio/transcriptions")
85
  async def transcribe_api(
86
  file: UploadFile = File(...),
87
- model: str = Form("whisper-1"), # 接收 openai 的 model 参数
88
- language: str = Form(None), # 接收指定的 ISO-639-1 语言代码(例如 zh, en)
89
- prompt: str = Form(None), # 忽略或预留
90
- response_format: str = Form("json"), # 接收输出格式:json, text 等
91
- temperature: float = Form(0.0) # 忽略或预留
92
  ):
93
  return await process_openai_audio_request(
94
  file=file,
@@ -98,7 +99,7 @@ async def transcribe_api(
98
  )
99
 
100
 
101
- # 4. 🎯 完美兼容接口二:语音翻译 (Translations - 强制输出英文)
102
  @app.post("/v1/audio/translations")
103
  async def translate_api(
104
  file: UploadFile = File(...),
 
8
  from fastapi.responses import JSONResponse, PlainTextResponse
9
  from transformers import pipeline
10
 
11
+ # 1. 声明加载模型
 
12
  MODEL_NAME = "openai/whisper-small"
13
+
14
+ # 2. 全局在 CPU 上初始化 Pipeline,防止启动时没有 GPU 报错
15
  pipe = pipeline(
16
  "automatic-speech-recognition",
17
  model=MODEL_NAME,
18
  chunk_length_s=30,
19
+ device="cpu"
20
  )
21
 
22
+ # 3. 核心修复】保留 @spaces.GPU 装饰器,确保 Hugging Face 启动扫描能够通过!
23
+ @spaces.GPU(duration=60)
24
  def transcribe_core(audio_path: str, target_language: str = None, is_translate: bool = False):
25
+ # 动态将模型转移至 A100 GPU 显存中
26
+ pipe.model.to("cuda")
27
 
28
+ generate_kwargs = {}
29
  if target_language:
30
  generate_kwargs["language"] = target_language
31
 
 
32
  if is_translate:
33
  generate_kwargs["language"] = "english"
34
  generate_kwargs["task"] = "translate"
35
 
36
+ # GPU 下执行极速推理
37
+ with torch.autocast("cuda"):
38
+ result = pipe(audio_path, generate_kwargs=generate_kwargs)
39
+
40
+ # 推理完成后立即释放,将模型转回 CPU
41
+ pipe.model.to("cpu")
42
  return result["text"]
43
 
44
  # --- Gradio 界面 ---
 
60
 
61
  app = demo.app
62
 
63
+ # --- 完美兼容 OpenAI 的处理函数 ---
64
  async def process_openai_audio_request(file, response_format, language, is_translate):
 
65
  suffix = os.path.splitext(file.filename)[1] or ".mp3"
66
  with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file:
67
  shutil.copyfileobj(file.file, temp_file)
68
  temp_path = temp_file.name
69
 
70
  try:
 
71
  text = transcribe_core(temp_path, target_language=language, is_translate=is_translate)
72
  except Exception as e:
73
  raise HTTPException(status_code=500, detail=f"OpenAI Audio API failed: {str(e)}")
 
75
  if os.path.exists(temp_path):
76
  os.remove(temp_path)
77
 
 
78
  if response_format in ["text", "vtt", "srt"]:
79
  return PlainTextResponse(text)
80
 
 
 
81
  return JSONResponse(content={"text": text})
82
 
83
 
84
+ # 4. 完美兼容接口一:语音转录 (Transcriptions)
85
  @app.post("/v1/audio/transcriptions")
86
  async def transcribe_api(
87
  file: UploadFile = File(...),
88
+ model: str = Form("whisper-1"),
89
+ language: str = Form(None),
90
+ prompt: str = Form(None),
91
+ response_format: str = Form("json"),
92
+ temperature: float = Form(0.0)
93
  ):
94
  return await process_openai_audio_request(
95
  file=file,
 
99
  )
100
 
101
 
102
+ # 5. 完美兼容接口二:语音翻译 (Translations)
103
  @app.post("/v1/audio/translations")
104
  async def translate_api(
105
  file: UploadFile = File(...),