Docker’da GPU Destekli OpenAI Whisper Modeli Çalıştırmak

Egemen Gulpinar
4 min readAug 18, 2024

--

Merhabalar, bu yazımda Whisper Large-v3 ve CUDA Destekli diğer yapay zeka modellerinin çalıştırılmasının nasıl sağlanacağını anlatıyor olacağım. İlgili docker konfigürasyonları adım adım takip etmeniz halinde sizlerde GPU desteğini aktif etmiş olacaksınız.

Öncelikle CUDA driverlarının kurulu olup çalıştığını teyit edelim

nvidia-smi
nvcc --version

Aşağıdaki gibi görüntüleniyorsa ilgili cihazınızın gerekli bağımlılıkları yüklü demektir.

Ardından, örnek olması açısından aşağıdaki customize edilmiş faster-whisper kütüphanesini kullanarak large-v3 modelini uygulamada aktif edeceğiz.

import datetime
import time
from faster_whisper import WhisperModel
from faster_whisper.vad import VadOptions
import torch
import re
class WhisperInference:
def __init__(self,thread_size: int):
model_size = "large-v3"
print("----CUDA------>" , torch.cuda.is_available())
print("----CUDA Current Device------>" , torch.cuda.current_device())
print("----CUDA Is Initialized------>" , torch.cuda.is_initialized())
print("----CUDA Memory Allocated------>" , torch.cuda.memory_allocated())
print("----CUDA Memory Reserved------>" , torch.cuda.memory_reserved())
print("----CUDA Memory Summary------>" , torch.cuda.memory_summary())
self.thread_size = thread_size
self.vad_options = VadOptions(threshold=0.55)
self.model = WhisperModel(model_size, device="CUDA", compute_type="float16",cpu_threads=thread_size)



def run_inference(self,clip_language: str,ad_id : int):
print("clip language --> ", clip_language)
segments, info = self.model.transcribe("../tmp/output.mp3", beam_size=3, language=clip_language,
vad_filter =True,vad_parameters=self.vad_options)
segments = list(segments)
print("Detected language '%s' with probability %f" % (info.language, info.language_probability))
return_subtitle = []
return_transcript = []
#handle segments whatever format you want
return segments

compute_type için aşağıdaki rehbere göz atabilirsiniz. Doğruluktan pay verip işlem hızını arttırmak mümkün.

Ayarlamalar bana ait, diğer kütüphaneler uygulamamın bir parçası ancak sizde bu model ayarlarını baz alabilirsiniz.

Devamında docker-compose.yml dosyasını oluşturalım.

version: '3.12'
services:
app:
build:
context: .
environment:
- PYTHONUNBUFFERED=1
- LD_LIBRARY_PATH=/usr/local/lib/python3.12/site-packages/nvidia/cublas/lib:/usr/local/lib/python3.12/site-packages/nvidia/cudnn/lib
volumes:
- .:/XXX_VOLUME_XXX
ports:
- "5000:5000"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
restart: always

docker-compose.yml dosyasında önemli olan kısımlar, LD_LIBRARY_PATH’in doğru verilmiş olması, bunu docker’in içine exec komutuyla girip öğrenebilir, veya aşağıdaki kodu çalıştırıp tüm print edilen path’i kopyalayabilirsiniz. Ancak genellikle konumlar sabit, sadece python sürümü farklı olmakta. Benim gibi Dockerfile kullandıysanız değiştirmenize gerek kalmayacaktır.

Eğer bu path doğru olmazsa, pathi öğrenmek için aşağıdaki ayarın sonucunu projenize entegre edin. Docker’daki konumunu tricky bir yoldan aşağıdaki şekilde çalıştırdığınızda loglar’dan bulabilirsiniz veya bunu direkt Docker’da yapmak sizin elinizde.

import nvidia.cublas.lib
import nvidia.cudnn.lib
print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))

Devamında deploy kısmında 1 adet GPU’muz olduğundan ilgili ayarlamalar aşağıdaki gibi tanımlandı.

  • driver : nvidia
  • count : 1
  • capabilities : [gpu]

.Dockerfile dosyamız ise aşağıdaki örnek gibi:

# Use Python 3.12 as the base image
FROM python:3.12

# Environment variables
ENV PYTHONUNBUFFERED=1

# Set the working directory
WORKDIR /livad-ad-speech-recognition

# Install essential packages
RUN apt-get update && apt-get install -y \
ffmpeg \
curl \
gnupg2 \
ca-certificates

# Add NVIDIA Container Toolkit repositories
RUN curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
&& curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# Update package lists and install NVIDIA Container Toolkit
RUN apt-get update \
&& apt-get install -y nvidia-container-toolkit

# Download and install CUDA and cuDNN libraries
RUN wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.0-1_all.deb && \
dpkg -i cuda-keyring_1.0-1_all.deb && \
apt-get update && apt-get upgrade -y && \
apt-get install -y libcudnn8 libcudnn8-dev

# Install Python dependencies
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

# Copy the cuDNN files check and copy script
COPY copy_cudnn_files.py /usr/local/bin/copy_cudnn_files.py
RUN python3 /usr/local/bin/copy_cudnn_files.py

# Copy application files
COPY scripts scripts
COPY main.py main.py
COPY src src

# Copy the Docker entrypoint script and make it executable
COPY docker-entrypoint.sh docker-entrypoint.sh
RUN chmod +x docker-entrypoint.sh

# Set the entry point
ENTRYPOINT ["./docker-entrypoint.sh"]

Requirement.txt şu şekilde:

torch
torchaudio
torchvision
pybind11
python-dotenv
faster-whisper
nvidia-cudnn-cu11
nvidia-cublas-cu11
numpy

Bu ayarlardan sonra build alalım:

docker-compose up --build -d

Önemli bir not

Çoğu kişi, “Could not load library libcudnn_ops_infer.so.8. Error: libcudnn_ops_infer.so.8” hatası almakta. Bunun çözümünü uzun araştırmalar sonucu Dockerfile’a aşağıdaki kod bloğunu ekleyerek yaptım.

RUN wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.0-1_all.deb && \
dpkg -i cuda-keyring_1.0-1_all.deb && \
apt-get update && apt-get upgrade -y && \
apt-get install -y libcudnn8 libcudnn8-dev

Bu adımı atlamamanız ve muhakkak yüklemeniz gerekmekte. Eğer sorun devam ederse, ilgili çalışacak ilk python koduna aşağıdaki kopyalama işlemini yapmalısınız.

import os
import shutil

def copy_cudnn_files():
try:
# Find the location of libcudnn_ops_infer.so.8
cudnn_path = None
for root, dirs, files in os.walk('/usr/'):
if 'libcudnn_ops_infer.so.8' in files:
cudnn_path = os.path.join(root, 'libcudnn_ops_infer.so.8')
break

# If the file is found, copy it to /usr/lib/
if cudnn_path:
cudnn_lib_dir = os.path.dirname(cudnn_path)
dest_dir = '/usr/lib/'
for file in os.listdir(cudnn_lib_dir):
if file.startswith('libcud'):
full_file_name = os.path.join(cudnn_lib_dir, file)
if os.path.isfile(full_file_name):
shutil.copy(full_file_name, dest_dir)
print(f"Library files successfully copied to {dest_dir}.")
else:
print("Required libcudnn_ops_infer.so.8 file not found.")

except Exception as e:
print(f"Error occurred during file copy: {e}")

# Start the file copy process
copy_cudnn_files()

Bu, ilgili dosyayı bulup usr/lib klasörüne kopyalamakta ve kod çalışırken bulmasını mümkün kılmaktadır.

Projeyi test ederken, loglar’da CUDA ile ilgili print edilen logları görmelisiniz. Bunları takip edin ve çalıştığını görün. Adımları doğru yaptığınız takdirde çalışacaktır. Docker’daki logları daha iyi takip edebilmek için “Portainer” kurmanızı tavsiye edebilirim.

Container Logs sekmesi altından rahatlıkla docker’daki loglar takip edilip geriye dönük yapılan işlemler de incelenebilir.

--

--

Egemen Gulpinar

I enjoy writing articles in Turkish and English languages, on everything I have been working on and experienced.