forked from KoljaB/RealtimeVoiceChat
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
193 lines (163 loc) · 6.82 KB
/
Dockerfile
File metadata and controls
193 lines (163 loc) · 6.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# Stage 1: Builder Stage - Install dependencies including build tools and CUDA toolkit components
FROM nvidia/cuda:12.1.1-cudnn8-devel-ubuntu22.04 AS builder
# Avoid prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive
# Install Python 3.10, pip, build essentials, git, and other system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
python3.10 \
python3-pip \
python3.10-dev \
python3.10-venv \
build-essential \
git \
libsndfile1 \
libportaudio2 \
ffmpeg \
portaudio19-dev \
python3-setuptools \
python3.10-distutils \
ninja-build \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Make python3.10 the default python/pip
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 && \
update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1
# Set working directory
WORKDIR /app
# Upgrade pip
RUN pip install --no-cache-dir --upgrade pip
# Install PyTorch with CUDA 12.1 support
RUN pip install --no-cache-dir \
torch==2.5.1+cu121 \
torchaudio==2.5.1+cu121 \
torchvision==0.20.1 \
--index-url https://download.pytorch.org/whl/cu121
# Install DeepSpeed
ENV DS_BUILD_TRANSFORMER=1
ENV DS_BUILD_CPU_ADAM=0
ENV DS_BUILD_FUSED_ADAM=0
ENV DS_BUILD_UTILS=0
ENV DS_BUILD_OPS=0
RUN echo "Building DeepSpeed with flags: DS_BUILD_TRANSFORMER=${DS_BUILD_TRANSFORMER}, DS_BUILD_CPU_ADAM=${DS_BUILD_CPU_ADAM}, DS_BUILD_FUSED_ADAM=${DS_BUILD_FUSED_ADAM}, DS_BUILD_UTILS=${DS_BUILD_UTILS}, DS_BUILD_OPS=${DS_BUILD_OPS}" && \
pip install --no-cache-dir deepspeed \
|| (echo "DeepSpeed install failed. Check build logs above." && exit 1)
# Copy requirements file first to leverage Docker cache
COPY requirements.txt .
# Install remaining Python dependencies from requirements.txt
RUN pip install --no-cache-dir --prefer-binary -r requirements.txt \
|| (echo "pip install -r requirements.txt FAILED." && exit 1)
# Pin ctranslate2 to a compatible version
RUN pip install --no-cache-dir "ctranslate2<4.5.0"
# Copy the application code
COPY code/ ./code/
# --- Stage 2: Runtime Stage ---
# Base image still needs CUDA toolkit for PyTorch/DeepSpeed/etc in the app
FROM nvidia/cuda:12.1.1-cudnn8-devel-ubuntu22.04
# Avoid prompts
ENV DEBIAN_FRONTEND=noninteractive
# Install runtime dependencies for the APP + gosu
RUN apt-get update && apt-get install -y --no-install-recommends \
python3.10 \
python3-pip \
python3.10-dev \
libsndfile1 \
ffmpeg \
libportaudio2 \
python3-setuptools \
python3.10-distutils \
ninja-build \
build-essential \
g++ \
curl \
gosu \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Make python3.10 the default python
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 && \
update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1
# Set working directory for the application
WORKDIR /app/code
# Copy installed Python packages from the builder stage
RUN mkdir -p /usr/local/lib/python3.10/dist-packages
COPY --from=builder /usr/local/lib/python3.10/dist-packages /usr/local/lib/python3.10/dist-packages
# Copy the application code from the builder stage
COPY --from=builder /app/code /app/code
# <<<--- Keep other model pre-downloads --->>>
# <<<--- Silero VAD Pre-download --->>>
RUN echo "Preloading Silero VAD model..." && \
python3 <<EOF
import torch
import os
try:
# Note: Downloads will happen as root here, ownership fixed later
cache_dir = os.path.expanduser("~/.cache/torch") # Will resolve to /root/.cache/torch
os.environ['TORCH_HOME'] = cache_dir
print(f"Using TORCH_HOME: {cache_dir}")
torch.hub.load(
repo_or_dir='snakers4/silero-vad',
model='silero_vad',
force_reload=False,
onnx=False,
trust_repo=True
)
print("Silero VAD download successful.")
except Exception as e:
print(f"Error downloading Silero VAD: {e}")
exit(1)
EOF
# <<<--- faster-whisper Pre-download --->>>
ARG WHISPER_MODEL=base.en
ENV WHISPER_MODEL=${WHISPER_MODEL}
RUN echo "Preloading faster_whisper model: ${WHISPER_MODEL}" && \
# Note: Downloads happen as root, cache dir likely ~/.cache/huggingface or similar
python3 -c "import os; print(f\"Downloading STT model: {os.getenv('WHISPER_MODEL')}\"); import faster_whisper; model = faster_whisper.WhisperModel(os.getenv('WHISPER_MODEL'), device='cpu'); print('Model download successful.')" \
|| (echo "Faster Whisper download failed" && exit 1)
# <<<--- SentenceFinishedClassification Pre-download --->>>
RUN echo "Preloading SentenceFinishedClassification model..." && \
# Note: Downloads happen as root
python3 -c "from transformers import DistilBertTokenizerFast, DistilBertForSequenceClassification; \
print('Downloading tokenizer...'); \
tokenizer = DistilBertTokenizerFast.from_pretrained('KoljaB/SentenceFinishedClassification'); \
print('Downloading classification model...'); \
model = DistilBertForSequenceClassification.from_pretrained('KoljaB/SentenceFinishedClassification'); \
print('Model downloads successful.')" \
|| (echo "Sentence Classifier download failed" && exit 1)
# Create a non-root user and group - DO NOT switch to it here
RUN groupadd --gid 1001 appgroup && \
useradd --uid 1001 --gid 1001 --create-home appuser
# Ensure directories are owned by appuser - This prepares the image layers correctly
# The entrypoint will handle runtime permissions for volumes/cache
RUN mkdir -p /home/appuser/.cache && \
chown -R appuser:appgroup /app && \
chown -R appuser:appgroup /usr/local/lib/python3.10/dist-packages && \
chown -R appuser:appgroup /home/appuser && \
# Also chown the caches potentially populated by root during build
if [ -d /root/.cache ]; then chown -R appuser:appgroup /root/.cache; fi
# Copy and set permissions for entrypoint script
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# --- REMOVED USER appuser --- The container will start as root.
# --- Keep ENV vars ---
ENV HOME=/home/appuser
ENV CUDA_HOME=/usr/local/cuda
ENV PATH="${CUDA_HOME}/bin:${PATH}"
ENV LD_LIBRARY_PATH="${CUDA_HOME}/lib64:${LD_LIBRARY_PATH}"
ENV PYTHONUNBUFFERED=1
ENV MAX_AUDIO_QUEUE_SIZE=50
ENV LOG_LEVEL=INFO
ENV NVIDIA_VISIBLE_DEVICES=all
ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility
ENV RUNNING_IN_DOCKER=true
ENV DS_BUILD_OPS=1
ENV DS_BUILD_CPU_ADAM=0
ENV DS_BUILD_FUSED_ADAM=0
ENV DS_BUILD_UTILS=0
ENV DS_BUILD_TRANSFORMER=1
ENV HF_HOME=${HOME}/.cache/huggingface
ENV TORCH_HOME=${HOME}/.cache/torch
# Expose the port the FastAPI application runs on
EXPOSE 8000
# Set the entrypoint script - This runs as root
ENTRYPOINT ["/entrypoint.sh"]
# Define the default command - This is passed as "$@" to the entrypoint script
CMD ["python", "-m", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8000"]