Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Soporte cuda #11

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .cog/openapi_schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"title":"Detail","type":"array"}},"title":"HTTPValidationError","type":"object"},"Input":{"properties":{"audio":{"description":"Audio file (mp3 or wav).","format":"uri","title":"Audio","type":"string","x-order":0},"bars":{"default":50,"description":"Number of bars on the video at once.","title":"Bars","type":"integer","x-order":6},"color":{"default":"0.03,0.6,0.3","description":"Color of the bars as 'r,g,b' in [0,1].","title":"Color","type":"string","x-order":3},"color2":{"default":"0.5,0.3,0.6","description":"Color of the second waveform for stereo files.","title":"Color2","type":"string","x-order":4},"duration":{"description":"Duration in seconds from seek time.","title":"Duration","type":"number","x-order":13},"height":{"default":300,"description":"Height of the animation in pixels.","title":"Height","type":"integer","x-order":11},"oversample":{"default":4,"description":"Lower values will feel less reactive.","title":"Oversample","type":"number","x-order":7},"rate":{"default":60,"description":"Video framerate.","title":"Rate","type":"integer","x-order":1},"seek":{"description":"Seek to time in seconds in video.","title":"Seek","type":"number","x-order":12},"speed":{"default":4,"description":"Faster transitions between frames.","title":"Speed","type":"number","x-order":9},"stereo":{"default":false,"description":"Create 2 waveforms for stereo files.","title":"Stereo","type":"boolean","x-order":2},"time_param":{"default":0.4,"description":"Amount of audio shown at once on a frame.","title":"Time Param","type":"number","x-order":8},"white":{"default":false,"description":"Use white background.","title":"White","type":"boolean","x-order":5},"width":{"default":480,"description":"Width of the animation in pixels.","title":"Width","type":"integer","x-order":10}},"required":["audio"],"title":"Input","type":"object"},"Output":{"format":"uri","title":"Output","type":"string"},"PredictionRequest":{"properties":{"created_at":{"format":"date-time","title":"Created At","type":"string"},"id":{"title":"Id","type":"string"},"input":{"$ref":"#/components/schemas/Input"},"output_file_prefix":{"title":"Output File Prefix","type":"string"},"webhook":{"format":"uri","maxLength":65536,"minLength":1,"title":"Webhook","type":"string"},"webhook_events_filter":{"default":["start","output","logs","completed"],"items":{"$ref":"#/components/schemas/WebhookEvent"},"type":"array"}},"title":"PredictionRequest","type":"object"},"PredictionResponse":{"properties":{"completed_at":{"format":"date-time","title":"Completed At","type":"string"},"created_at":{"format":"date-time","title":"Created At","type":"string"},"error":{"title":"Error","type":"string"},"id":{"title":"Id","type":"string"},"input":{"$ref":"#/components/schemas/Input"},"logs":{"default":"","title":"Logs","type":"string"},"metrics":{"title":"Metrics","type":"object"},"output":{"$ref":"#/components/schemas/Output"},"started_at":{"format":"date-time","title":"Started At","type":"string"},"status":{"$ref":"#/components/schemas/Status"},"version":{"title":"Version","type":"string"}},"title":"PredictionResponse","type":"object"},"Status":{"description":"An enumeration.","enum":["starting","processing","succeeded","canceled","failed"],"title":"Status","type":"string"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"title":"Location","type":"array"},"msg":{"title":"Message","type":"string"},"type":{"title":"Error Type","type":"string"}},"required":["loc","msg","type"],"title":"ValidationError","type":"object"},"WebhookEvent":{"description":"An enumeration.","enum":["start","output","logs","completed"],"title":"WebhookEvent","type":"string"}}},"info":{"title":"Cog","version":"0.1.0"},"openapi":"3.0.2","paths":{"/":{"get":{"operationId":"root__get","responses":{"200":{"content":{"application/json":{"schema":{"title":"Response Root Get"}}},"description":"Successful Response"}},"summary":"Root"}},"/health-check":{"get":{"operationId":"healthcheck_health_check_get","responses":{"200":{"content":{"application/json":{"schema":{"title":"Response Healthcheck Health Check Get"}}},"description":"Successful Response"}},"summary":"Healthcheck"}},"/predictions":{"post":{"description":"Run a single prediction on the model","operationId":"predict_predictions_post","parameters":[{"in":"header","name":"prefer","required":false,"schema":{"title":"Prefer","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionRequest"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Predict"}},"/predictions/{prediction_id}":{"put":{"description":"Run a single prediction on the model (idempotent creation).","operationId":"predict_idempotent_predictions__prediction_id__put","parameters":[{"in":"path","name":"prediction_id","required":true,"schema":{"title":"Prediction ID","type":"string"}},{"in":"header","name":"prefer","required":false,"schema":{"title":"Prefer","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PredictionRequest"}],"title":"Prediction Request"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Predict Idempotent"}},"/predictions/{prediction_id}/cancel":{"post":{"description":"Cancel a running prediction","operationId":"cancel_predictions__prediction_id__cancel_post","parameters":[{"in":"path","name":"prediction_id","required":true,"schema":{"title":"Prediction ID","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"title":"Response Cancel Predictions Prediction Id Cancel Post"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"summary":"Cancel"}},"/shutdown":{"post":{"operationId":"start_shutdown_shutdown_post","responses":{"200":{"content":{"application/json":{"schema":{"title":"Response Start Shutdown Shutdown Post"}}},"description":"Successful Response"}},"summary":"Start Shutdown"}}}}
17 changes: 17 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# The .dockerignore file excludes files from the container build process.
#
# https://docs.docker.com/engine/reference/builder/#dockerignore-file

# Exclude Git files
**/.git
**/.github
**/.gitignore

# Exclude Python cache files
__pycache__
.mypy_cache
.pytest_cache
.ruff_cache

# Exclude Python virtual environment
/venv
54 changes: 54 additions & 0 deletions .github/workflows/push.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Push to Replicate

on:
# Workflow dispatch allows you to manually trigger the workflow from GitHub.com
# Go to your repo, click "Actions", click "Push to Replicate", click "Run workflow"
workflow_dispatch:
inputs:
model_name:
description: 'Enter the model name, like "alice/bunny-detector". If unset, this will default to the value of `image` in cog.yaml.'
# # Uncomment these lines to trigger the workflow on every push to the main branch
# push:
# branches:
# - main

jobs:
push_to_replicate:
name: Push to Replicate

# If your model is large, the default GitHub Actions runner may not
# have enough disk space. If you need more space you can set up a
# bigger runner on GitHub.
runs-on: ubuntu-latest

steps:
# This action cleans up disk space to make more room for your
# model code, weights, etc.
- name: Free disk space
uses: jlumbroso/[email protected]
with:
tool-cache: false
docker-images: false

- name: Checkout
uses: actions/checkout@v4

# This action installs Docker buildx and Cog (and optionally CUDA)
- name: Setup Cog
uses: replicate/setup-cog@v2
with:
# If you set REPLICATE_API_TOKEN in your GitHub repository secrets,
# the action will authenticate with Replicate automatically so you
# can push your model
token: ${{ secrets.REPLICATE_API_TOKEN }}

# If you trigger the workflow manually, you can specify the model name.
# If you leave it blank (or if the workflow is triggered by a push), the
# model name will be derived from the `image` value in cog.yaml.
- name: Push to Replicate
run: |
if [ -n "${{ inputs.model_name }}" ]; then
cog push r8.im/${{ inputs.model_name }}
else
cog push
fi
37 changes: 37 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
FROM nvidia/cuda:12.1.1-runtime-ubuntu20.04

# Configurar entorno no interactivo
ENV DEBIAN_FRONTEND=noninteractive

# Instalar dependencias del sistema
RUN apt-get update && apt-get install -y \
python3.9 \
python3.9-dev \
libcairo2-dev \
libjpeg-dev \
libgif-dev \
libpng-dev \
meson \
ninja-build \
build-essential \
ffmpeg \
git \
&& rm -rf /var/lib/apt/lists/*

# Crear y establecer el directorio de trabajo
WORKDIR /app

# Copiar archivos del proyecto
COPY . /app

# Actualizar pip e instalar dependencias
RUN python3.9 -m pip install --upgrade pip && \
python3.9 -m pip install -r requirements.txt && \
python3.9 -m pip uninstall -y pycairo && \
python3.9 -m pip install pycairo \
python3.9 -m pip uninstall cog -y \
python3.9 -m pip pip install cog

# Comando de entrada
ENTRYPOINT ["python3"]

Binary file added audiofile.mp3
Binary file not shown.
31 changes: 31 additions & 0 deletions cog.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
build:
python_version: "3.9" # Define la versión de Python
gpu: true # Habilitar soporte para GPU
cuda: "12.1" # Especificar la versión de CUDA compatible con cupy-cuda12x
python_packages:
- cupy-cuda12x==11.6.0
- fastrlock==0.8.2
- imageio==2.31.2
- imageio-ffmpeg==0.5.1
- numpy==1.21.6
- Pillow==9.5.0
- psutil==6.1.0
- tqdm==4.67.0
system_packages:
- libcairo2-dev # Necesario para pycairo
- libjpeg-dev
- libgif-dev
- libpng-dev
- meson
- ninja-build
- build-essential
- ffmpeg
- git
run:
- pip install --upgrade pip
- pip uninstall -y pycairo # Reinstalar pycairo para asegurar compatibilidad
- pip install pycairo
- pip uninstall cog -y
- pip install cog

predict: "predict.py:Predictor" # Punto de entrada para predicciones
70 changes: 70 additions & 0 deletions predict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import os
import subprocess
from cog import BasePredictor, Input, Path

class Predictor(BasePredictor):
def predict(
self,
audio: Path = Input(description="Audio file (mp3 or wav)."),
rate: int = Input(description="Video framerate.", default=60),
stereo: bool = Input(description="Create 2 waveforms for stereo files.", default=False),
color: str = Input(description="Color of the bars as 'r,g,b' in [0,1].", default="0.03,0.6,0.3"),
color2: str = Input(description="Color of the second waveform for stereo files.", default="0.5,0.3,0.6"),
white: bool = Input(description="Use white background.", default=False),
bars: int = Input(description="Number of bars on the video at once.", default=50),
oversample: float = Input(description="Lower values will feel less reactive.", default=4.0),
time_param: float = Input(description="Amount of audio shown at once on a frame.", default=0.4),
speed: float = Input(description="Faster transitions between frames.", default=4.0),
width: int = Input(description="Width of the animation in pixels.", default=480),
height: int = Input(description="Height of the animation in pixels.", default=300),
seek: float = Input(description="Seek to time in seconds in video.", default=None),
duration: float = Input(description="Duration in seconds from seek time.", default=None),
) -> Path:
"""
Procesa el archivo de audio subido y devuelve un archivo MP4.
"""
# Ruta de salida para el archivo generado
output_path = Path("/src/out.mp4")
os.makedirs(os.path.dirname(output_path), exist_ok=True)

# Construir el comando como una lista
command = [
"/root/.pyenv/shims/python3",
os.path.join('/src/seewav.py'),
"-r", str(rate),
"-c", color,
"-c2", color2,
"-B", str(bars),
"-O", str(oversample),
"-T", str(time_param),
"-S", str(speed),
"-W", str(width),
"-H", str(height),
str(audio),
str(output_path)
]

if stereo:
command.append("--stereo")
if white:
command.append("--white")
if seek is not None:
command.extend(["-s", str(seek)])
if duration is not None:
command.extend(["-d", str(duration)])

# Imprimir el comando para depuración
print("Comando a ejecutar:", " ".join(command))

# Ejecutar el comando y capturar la salida
result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

# Imprimir la salida y errores para depuración
print("STDOUT:", result.stdout)
print("STDERR:", result.stderr)

# Verificar si el archivo de salida se ha generado correctamente
if not os.path.exists(output_path) or os.path.getsize(output_path) == 0:
raise RuntimeError("El archivo de salida no se ha generado correctamente.")

return output_path # Devolver la ruta del archivo de salida
12 changes: 9 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
numpy
pycairo
tqdm
cupy-cuda12x==11.6.0
fastrlock==0.8.2
imageio==2.31.2
imageio-ffmpeg==0.5.1
numpy==1.21.6
Pillow==9.5.0
psutil==6.1.0
pycairo==1.23.0
tqdm==4.67.0
Loading