v-e-n-o-m commited on
Commit
ce0204b
·
1 Parent(s): ddf65c1
Files changed (2) hide show
  1. Dockerfile +3 -3
  2. app.py +17 -5
Dockerfile CHANGED
@@ -24,8 +24,8 @@ COPY app.py .
24
  # Set environment variable for Hugging Face cache
25
  ENV HF_HOME=/app/cache
26
 
27
- # Expose port
28
  EXPOSE 8000
29
 
30
- # Run the FastAPI app with uvicorn
31
- CMD ["sh", "-c", "uvicorn app:app --host 0.0.0.0 --port ${PORT:-8000}"]
 
24
  # Set environment variable for Hugging Face cache
25
  ENV HF_HOME=/app/cache
26
 
27
+ # Expose default port (can be overridden by PORT env var)
28
  EXPOSE 8000
29
 
30
+ # Run the FastAPI app with uvicorn, using PORT env var
31
+ CMD ["sh", "-c", "uvicorn app:app --host 0.0.0.0 --port ${PORT:-8000} --workers 1"]
app.py CHANGED
@@ -10,6 +10,7 @@ import subprocess
10
  import tempfile
11
  from contextlib import contextmanager
12
 
 
13
  logging.basicConfig(
14
  level=logging.INFO,
15
  format="%(asctime)s [%(levelname)s] %(message)s",
@@ -20,6 +21,7 @@ logging.basicConfig(
20
  )
21
  logger = logging.getLogger(__name__)
22
 
 
23
  logger.info(f"Python version: {sys.version}")
24
  try:
25
  import transformers
@@ -30,26 +32,33 @@ except ImportError as e:
30
  logger.error(f"Failed to import dependency: {str(e)}")
31
  raise
32
 
 
33
  os.makedirs("/app/cache", exist_ok=True)
34
  os.environ["HF_HOME"] = "/app/cache"
35
  logger.info(f"Set HF_HOME to /app/cache")
36
 
 
37
  app = FastAPI(title="Quran Transcription API")
38
 
 
39
  @app.get("/health", status_code=200)
40
  async def health_check():
41
  logger.info("Health check requested")
42
  return {"status": "healthy", "model_loaded": model is not None}
43
 
 
44
  @app.get("/debug")
45
  async def debug():
 
46
  return {
47
  "cuda_available": torch.cuda.is_available(),
48
  "model_loaded": model is not None,
49
  "pipeline_initialized": asr is not None,
50
- "cache_dir": os.getenv("HF_HOME")
 
51
  }
52
 
 
53
  try:
54
  model_id = "tarteel-ai/whisper-base-ar-quran"
55
  logger.info(f"Loading processor for model: {model_id}")
@@ -61,6 +70,7 @@ except Exception as e:
61
  logger.error(f"Failed to load model: {str(e)}")
62
  raise HTTPException(status_code=500, detail="Model loading failed")
63
 
 
64
  try:
65
  logger.info("Initializing ASR pipeline")
66
  asr = pipeline(
@@ -68,7 +78,7 @@ try:
68
  model=model,
69
  tokenizer=processor.tokenizer,
70
  feature_extractor=processor.feature_extractor,
71
- device=-1 # Force CPU for testing
72
  )
73
  except Exception as e:
74
  logger.error(f"Failed to initialize ASR pipeline: {str(e)}")
@@ -111,7 +121,8 @@ async def transcribe_audio(file: UploadFile = File(...)):
111
  ["ffmpeg", "-i", temp_mp3.name, "-ar", "16000", "-ac", "1", "-y", temp_wav_path],
112
  check=True,
113
  capture_output=True,
114
- text=True
 
115
  )
116
  logger.debug(f"ffmpeg output: {result.stdout}")
117
  except subprocess.CalledProcessError as e:
@@ -145,11 +156,12 @@ async def startup_event():
145
  logger.info(f"Memory allocated: {torch.cuda.memory_allocated() if torch.cuda.is_available() else 'N/A'}")
146
 
147
  if __name__ == "__main__":
148
- port = int(os.getenv("PORT", 8000))
149
  logger.info(f"Starting Uvicorn server on port {port}")
150
  uvicorn.run(
151
  "app:app",
152
  host="0.0.0.0",
153
  port=port,
154
- log_level="info"
 
155
  )
 
10
  import tempfile
11
  from contextlib import contextmanager
12
 
13
+ # Configure logging
14
  logging.basicConfig(
15
  level=logging.INFO,
16
  format="%(asctime)s [%(levelname)s] %(message)s",
 
21
  )
22
  logger = logging.getLogger(__name__)
23
 
24
+ # Log system information
25
  logger.info(f"Python version: {sys.version}")
26
  try:
27
  import transformers
 
32
  logger.error(f"Failed to import dependency: {str(e)}")
33
  raise
34
 
35
+ # Set up cache directory
36
  os.makedirs("/app/cache", exist_ok=True)
37
  os.environ["HF_HOME"] = "/app/cache"
38
  logger.info(f"Set HF_HOME to /app/cache")
39
 
40
+ # Initialize FastAPI app
41
  app = FastAPI(title="Quran Transcription API")
42
 
43
+ # Health check endpoint
44
  @app.get("/health", status_code=200)
45
  async def health_check():
46
  logger.info("Health check requested")
47
  return {"status": "healthy", "model_loaded": model is not None}
48
 
49
+ # Debug endpoint
50
  @app.get("/debug")
51
  async def debug():
52
+ logger.info("Debug endpoint requested")
53
  return {
54
  "cuda_available": torch.cuda.is_available(),
55
  "model_loaded": model is not None,
56
  "pipeline_initialized": asr is not None,
57
+ "cache_dir": os.getenv("HF_HOME"),
58
+ "port": os.getenv("PORT", "8000")
59
  }
60
 
61
+ # Load model and processor
62
  try:
63
  model_id = "tarteel-ai/whisper-base-ar-quran"
64
  logger.info(f"Loading processor for model: {model_id}")
 
70
  logger.error(f"Failed to load model: {str(e)}")
71
  raise HTTPException(status_code=500, detail="Model loading failed")
72
 
73
+ # Initialize ASR pipeline
74
  try:
75
  logger.info("Initializing ASR pipeline")
76
  asr = pipeline(
 
78
  model=model,
79
  tokenizer=processor.tokenizer,
80
  feature_extractor=processor.feature_extractor,
81
+ device=-1 # Force CPU
82
  )
83
  except Exception as e:
84
  logger.error(f"Failed to initialize ASR pipeline: {str(e)}")
 
121
  ["ffmpeg", "-i", temp_mp3.name, "-ar", "16000", "-ac", "1", "-y", temp_wav_path],
122
  check=True,
123
  capture_output=True,
124
+ text=True,
125
+ timeout=30
126
  )
127
  logger.debug(f"ffmpeg output: {result.stdout}")
128
  except subprocess.CalledProcessError as e:
 
156
  logger.info(f"Memory allocated: {torch.cuda.memory_allocated() if torch.cuda.is_available() else 'N/A'}")
157
 
158
  if __name__ == "__main__":
159
+ port = int(os.getenv("PORT", 8000)) # Use PORT env var or default to 8000
160
  logger.info(f"Starting Uvicorn server on port {port}")
161
  uvicorn.run(
162
  "app:app",
163
  host="0.0.0.0",
164
  port=port,
165
+ log_level="info",
166
+ workers=1 # Single worker to avoid resource issues
167
  )