Matir commited on
Commit
55fc4e0
·
1 Parent(s): 1ac3a4d

Update image

Browse files
Files changed (2) hide show
  1. Dockerfile +3 -1
  2. main.py +34 -8
Dockerfile CHANGED
@@ -18,5 +18,7 @@ COPY main.py .
18
  # Expose port 8080
19
  EXPOSE 8080
20
 
 
 
21
  # Start uvicorn
22
- CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]
 
18
  # Expose port 8080
19
  EXPOSE 8080
20
 
21
+ ENV PYTHONUNBUFFERED=1
22
+
23
  # Start uvicorn
24
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080", "--log-level", "debug"]
main.py CHANGED
@@ -1,13 +1,18 @@
1
- import io
2
  from importlib.metadata import version
3
- import tempfile
4
- import os
5
  import base64
6
- from typing import Dict, Any
7
  import logging
8
- from contextlib import asynccontextmanager
 
 
 
9
 
10
  from fastapi import FastAPI, Request, Response, HTTPException
 
 
 
11
 
12
  # this must come before attempts to import from transformers or torch
13
  print(f'Versions: transformers: {version("transformers")}, torch: {version("torch")}')
@@ -99,11 +104,19 @@ class EndpointHandler():
99
  # If already loaded (e.g. numpy array passed in some test environments)
100
  audio_array = inputs
101
 
102
- # 3. Prepare inputs using the recommended API
103
  processed_inputs = self.processor.apply_transcription_request(
104
  audio=audio_array,
105
  prompt=hotwords
106
- ).to(self.model.device, self.model.dtype)
 
 
 
 
 
 
 
 
 
107
 
108
  # 4. Generate
109
  with torch.no_grad():
@@ -130,6 +143,7 @@ class EndpointHandler():
130
  return {"result": transcription}
131
 
132
  except Exception as e:
 
133
  return {"error": f"Inference failed: {str(e)}"}
134
 
135
  finally:
@@ -175,9 +189,21 @@ async def predict(request: Request):
175
  # Fallback to raw bytes
176
  data = await request.body()
177
 
178
- response = handler(data)
179
 
180
  if "error" in response:
181
  raise HTTPException(status_code=500, detail=response["error"])
182
 
183
  return response
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from contextlib import asynccontextmanager
2
  from importlib.metadata import version
3
+ import asyncio
 
4
  import base64
5
+ import io
6
  import logging
7
+ import os
8
+ import sys
9
+ import tempfile
10
+ import traceback
11
 
12
  from fastapi import FastAPI, Request, Response, HTTPException
13
+ from fastapi.responses import JSONResponse
14
+
15
+ from typing import Dict, Any
16
 
17
  # this must come before attempts to import from transformers or torch
18
  print(f'Versions: transformers: {version("transformers")}, torch: {version("torch")}')
 
104
  # If already loaded (e.g. numpy array passed in some test environments)
105
  audio_array = inputs
106
 
 
107
  processed_inputs = self.processor.apply_transcription_request(
108
  audio=audio_array,
109
  prompt=hotwords
110
+ )
111
+
112
+ # Safely move to device and cast ONLY floating point tensors to the model's dtype.
113
+ # Casting integer tensors (like input_ids) to bfloat16/float16 will cause model errors.
114
+ for k, v in processed_inputs.items():
115
+ if isinstance(v, torch.Tensor):
116
+ if torch.is_floating_point(v):
117
+ processed_inputs[k] = v.to(device=self.model.device, dtype=self.model.dtype)
118
+ else:
119
+ processed_inputs[k] = v.to(device=self.model.device)
120
 
121
  # 4. Generate
122
  with torch.no_grad():
 
143
  return {"result": transcription}
144
 
145
  except Exception as e:
146
+ logger.exception("Inference failed due to exception", e)
147
  return {"error": f"Inference failed: {str(e)}"}
148
 
149
  finally:
 
189
  # Fallback to raw bytes
190
  data = await request.body()
191
 
192
+ response = await asyncio.to_thread(handler, data)
193
 
194
  if "error" in response:
195
  raise HTTPException(status_code=500, detail=response["error"])
196
 
197
  return response
198
+
199
+ @app.exception_handler(Exception)
200
+ async def global_exception_handler(request: Request, exc: Exception):
201
+ # Force print to stderr
202
+ print(f"CRITICAL ERROR: {str(exc)}", file=sys.stderr)
203
+ print(traceback.format_exc(), file=sys.stderr)
204
+
205
+ # Return the error in the payload so you can see it in your HTTP client
206
+ return JSONResponse(
207
+ status_code=500,
208
+ content={"error": str(exc), "type": str(type(exc))}
209
+ )