anfastech commited on
Commit
a108752
Β·
1 Parent(s): f233d84

Optimizing the Dockerfile: fixing dependency installation order, adding build tools, and resolving potential conflicts

Browse files
Files changed (3) hide show
  1. Dockerfile +6 -14
  2. app.py +10 -18
  3. requirements.txt +1 -6
Dockerfile CHANGED
@@ -2,37 +2,29 @@ FROM python:3.10-slim
2
 
3
  WORKDIR /app
4
 
5
- # Install system dependencies FIRST (including build tools for compiling packages)
6
  RUN apt-get update && apt-get install -y \
7
  ffmpeg \
8
  libsndfile1 \
9
- build-essential \
10
  && rm -rf /var/lib/apt/lists/*
11
 
12
- # Upgrade pip and install wheel first
13
- RUN pip install --upgrade pip setuptools wheel
14
-
15
- # Copy requirements early for better Docker layer caching
16
  COPY requirements.txt .
17
 
18
  # Install Python dependencies in CORRECT ORDER
19
- # numpy MUST be installed first, before torch/torchaudio (prevents conflicts)
20
  RUN pip install --no-cache-dir "numpy>=1.24.0,<2.0.0"
21
 
22
- # Install remaining requirements
23
- # numpy is already installed above, pip will skip it if version matches
24
- # Use --prefer-binary to prefer pre-built wheels (faster, more reliable)
25
- RUN pip install --no-cache-dir --prefer-binary -r requirements.txt
26
 
27
  # Copy application code
28
  COPY . .
29
 
30
- # Expose port (HuggingFace Spaces uses 7860)
31
  EXPOSE 7860
32
 
33
- # Set environment variables
34
  ENV PYTHONUNBUFFERED=1
35
- ENV PORT=7860
36
 
37
  # Run with uvicorn directly (required for HuggingFace Spaces)
38
  # Use PORT environment variable if provided, otherwise default to 7860
 
2
 
3
  WORKDIR /app
4
 
5
+ # Install system dependencies FIRST
6
  RUN apt-get update && apt-get install -y \
7
  ffmpeg \
8
  libsndfile1 \
 
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
+ # Copy requirements
 
 
 
12
  COPY requirements.txt .
13
 
14
  # Install Python dependencies in CORRECT ORDER
15
+ # numpy MUST be first, before torch/torchaudio
16
  RUN pip install --no-cache-dir "numpy>=1.24.0,<2.0.0"
17
 
18
+ RUN pip install --no-cache-dir -r requirements.txt
 
 
 
19
 
20
  # Copy application code
21
  COPY . .
22
 
23
+ # Expose port
24
  EXPOSE 7860
25
 
26
+ # Run with proper Python settings
27
  ENV PYTHONUNBUFFERED=1
 
28
 
29
  # Run with uvicorn directly (required for HuggingFace Spaces)
30
  # Use PORT environment variable if provided, otherwise default to 7860
app.py CHANGED
@@ -3,7 +3,7 @@ import logging
3
  import os
4
  import sys
5
  from pathlib import Path
6
- from fastapi import FastAPI, UploadFile, File, Form, HTTPException
7
  from fastapi.responses import JSONResponse
8
  from fastapi.middleware.cors import CORSMiddleware
9
 
@@ -55,10 +55,7 @@ async def startup_event():
55
  logger.info("βœ… Models loaded successfully!")
56
  except Exception as e:
57
  logger.error(f"❌ Failed to load models: {e}", exc_info=True)
58
- # Don't raise - allow app to start and return 503 on analyze requests
59
- # This allows HuggingFace Spaces to show the app is running
60
- logger.warning("⚠️ App will start but models are not loaded. Analyze requests will return 503.")
61
- detector = None
62
 
63
  @app.get("/health")
64
  async def health_check():
@@ -73,8 +70,7 @@ async def health_check():
73
  @app.post("/analyze")
74
  async def analyze_audio(
75
  audio: UploadFile = File(...),
76
- transcript: str = Form(""),
77
- language: str = Form("english")
78
  ):
79
  """
80
  Analyze audio file for stuttering
@@ -82,7 +78,6 @@ async def analyze_audio(
82
  Parameters:
83
  - audio: WAV or MP3 audio file
84
  - transcript: Optional expected transcript
85
- - language: Language code (e.g., 'hindi', 'english', 'tamil'). Defaults to 'english'
86
 
87
  Returns: Complete stutter analysis results
88
  """
@@ -91,7 +86,7 @@ async def analyze_audio(
91
  if not detector:
92
  raise HTTPException(status_code=503, detail="Models not loaded yet. Try again in a moment.")
93
 
94
- logger.info(f"πŸ“₯ Processing: {audio.filename} [Language: {language}]")
95
 
96
  # Create temp directory if needed
97
  temp_dir = "/tmp/stutter_analysis"
@@ -106,10 +101,9 @@ async def analyze_audio(
106
 
107
  logger.info(f"πŸ“‚ Saved to: {temp_file} ({len(content) / 1024 / 1024:.2f} MB)")
108
 
109
- # Analyze with language parameter
110
- transcript_preview = transcript[:50] if transcript else "None"
111
- logger.info(f"πŸ”„ Analyzing audio with transcript: '{transcript_preview}...' [Language: {language}]")
112
- result = detector.analyze_audio(temp_file, transcript, language=language)
113
 
114
  logger.info(f"βœ… Analysis complete: severity={result['severity']}, mismatch={result['mismatch_percentage']}%")
115
  return result
@@ -138,7 +132,7 @@ async def root():
138
  "status": "running",
139
  "endpoints": {
140
  "health": "GET /health",
141
- "analyze": "POST /analyze (multipart form: audio file, transcript (optional), language (optional, default: 'english'))",
142
  "docs": "GET /docs (interactive API docs)"
143
  },
144
  "models": {
@@ -150,12 +144,10 @@ async def root():
150
 
151
  if __name__ == "__main__":
152
  import uvicorn
153
- # Read port from environment variable (HuggingFace Spaces provides this)
154
- port = int(os.environ.get("PORT", 7860))
155
- logger.info(f"πŸš€ Starting SLAQ Stutter Detector API on port {port}...")
156
  uvicorn.run(
157
  app,
158
  host="0.0.0.0",
159
- port=port,
160
  log_level="info"
161
  )
 
3
  import os
4
  import sys
5
  from pathlib import Path
6
+ from fastapi import FastAPI, UploadFile, File, HTTPException
7
  from fastapi.responses import JSONResponse
8
  from fastapi.middleware.cors import CORSMiddleware
9
 
 
55
  logger.info("βœ… Models loaded successfully!")
56
  except Exception as e:
57
  logger.error(f"❌ Failed to load models: {e}", exc_info=True)
58
+ raise
 
 
 
59
 
60
  @app.get("/health")
61
  async def health_check():
 
70
  @app.post("/analyze")
71
  async def analyze_audio(
72
  audio: UploadFile = File(...),
73
+ transcript: str = ""
 
74
  ):
75
  """
76
  Analyze audio file for stuttering
 
78
  Parameters:
79
  - audio: WAV or MP3 audio file
80
  - transcript: Optional expected transcript
 
81
 
82
  Returns: Complete stutter analysis results
83
  """
 
86
  if not detector:
87
  raise HTTPException(status_code=503, detail="Models not loaded yet. Try again in a moment.")
88
 
89
+ logger.info(f"πŸ“₯ Processing: {audio.filename}")
90
 
91
  # Create temp directory if needed
92
  temp_dir = "/tmp/stutter_analysis"
 
101
 
102
  logger.info(f"πŸ“‚ Saved to: {temp_file} ({len(content) / 1024 / 1024:.2f} MB)")
103
 
104
+ # Analyze
105
+ logger.info(f"πŸ”„ Analyzing audio with transcript: '{transcript[:50]}...'")
106
+ result = detector.analyze_audio(temp_file, transcript)
 
107
 
108
  logger.info(f"βœ… Analysis complete: severity={result['severity']}, mismatch={result['mismatch_percentage']}%")
109
  return result
 
132
  "status": "running",
133
  "endpoints": {
134
  "health": "GET /health",
135
+ "analyze": "POST /analyze (multipart: audio file + optional transcript field)",
136
  "docs": "GET /docs (interactive API docs)"
137
  },
138
  "models": {
 
144
 
145
  if __name__ == "__main__":
146
  import uvicorn
147
+ logger.info("πŸš€ Starting SLAQ Stutter Detector API...")
 
 
148
  uvicorn.run(
149
  app,
150
  host="0.0.0.0",
151
+ port=7860,
152
  log_level="info"
153
  )
requirements.txt CHANGED
@@ -1,5 +1,5 @@
1
  # Core ML Dependencies - ORDER MATTERS!
2
- # Note: In Dockerfile, numpy is installed separately first to prevent conflicts
3
  numpy>=1.24.0,<2.0.0
4
  torch==2.0.1
5
  torchaudio==2.0.2
@@ -9,11 +9,6 @@ transformers==4.35.0
9
  # Audio Processing
10
  soundfile>=0.12.1
11
  scipy>=1.11.0
12
- parselmouth>=0.4.0
13
-
14
- # Machine Learning
15
- scikit-learn>=1.3.0
16
- fastdtw>=0.3.0
17
 
18
  # API Framework
19
  fastapi==0.104.1
 
1
  # Core ML Dependencies - ORDER MATTERS!
2
+
3
  numpy>=1.24.0,<2.0.0
4
  torch==2.0.1
5
  torchaudio==2.0.2
 
9
  # Audio Processing
10
  soundfile>=0.12.1
11
  scipy>=1.11.0
 
 
 
 
 
12
 
13
  # API Framework
14
  fastapi==0.104.1