Subtitular películas con Whisper
Estoy tratando de aprender portugués viendo películas. Lo ideal es tener los subtítulos en portugués, e ir consultando cuando aparecen palabras nuevas. Esto funciona excelente con las plataformas, donde pude ver Ciudad de Dios, pero se complica cuando hay que recurrir a los corsarios 🏴☠️ para proveerse de cultura.
Una peli que tengo muchas ganas de ver es O Auto da Compadecida, que solo encontré sin subtítulos. Se me ocurrió usar Whisper para transcribir el audio directamente. Como tengo una Mac nueva con GPU, pensé que el modelo podía andar bien localmente, pero Whisper no es compatible con la GPU de mi MAC, y con la CPU es bastante lento así que usé una instancia EC2 en AWS.
AWS
EC2 tiene una AMI con Ubuntu preparada para tareas de deep learning. El tipo de instancia es el más barato con GPUs: g4dn.xlarge
. Una vez lanzada la instancia, actualizamos el OS e instalamos los requerimientos:
# actualizar el OS
sudo apt update && sudo apt install -y ffmpeg
# instalar las dependencias:
sudo apt install -y python3-venv python3-pip
# crear ambiente virtual
python3 -m venv whisper_env
# activarlo
source whisper_env/bin/activate
# instalar whisper
pip install openai-whisper
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
ffmpeg
puede extraer un archivo mp3 de un archivo de video:
ffmpeg -i o_auto_da_compadecida.mp4 -vn -acodec libmp3lame o_auto_da_compadecida.mp3
Para subirlo a la instancia tenemos dos opciones: scp o S3. Copiamos el mp3 con scp
y
nos logueamos a la instancia para correr whisper:
whisper o_auto_da_compadecida.mp3 --model medium --language Portuguese --task transcribe --output_format srt
head -n 10 o_auto_da_compadecida.srt
La transcripción tiene algunos problemas al principio, pero después parece dar bien (aunque habría que mirar la peli completa para verifarlo). Hay que tener en cuenta que esta instancia es cara
(~ 0.5 USD/hora) por lo que hay que pararla cuando no la usomos. La dejé prendida una noche sin
usarla y me salió como 5 USD. Lección aprendida. Subir los archivos a S3 en vez de usar scp
también puede ser mejor.
Automatizar AWS
La solución que se me ocurre para automatizar un poco el proceso es subir el archivo a S3 y configurar lambda para que lance la instancia, corra whisper, suba el archivo srt a S3 de vuelta y termine la instancia.
Lo primero que hay que resolver bien es el tema de los permisos. La instancia que corre whisper tiene que tener permisos para leer y escribir en S3. Lo más complejo es que lambda tiene que tener permisos para crear una instancia y asignarle los permisos para leer y escribir a S3.
La función lambda es invocada cuando alguien sube un mp3 al bucket, toma el nombre del archivo, lanza la instancia y la configura con un script user_data. Este script:
- Instala los requerimientos
- Descarga el archivo de S3
- Corre whisper con ese archivo
- Sube el srt a S3
- Termina la instancia
import boto3
ec2 = boto3.client("ec2")
AMI_ID = "ami-0a844bb563d863f8c"
INSTANCE_TYPE = "g4dn.xlarge"
S3_BUCKET = "INPUT_BUCKET"
S3_OUTPUT_BUCKET = "OUTPUT_BUCKET"
SECURITY_GROUP_ID = "sg-0f5fec4ef93ab7b79"
def lambda_handler(event, context):
# Extract audio file name from the event
s3_object = event["Records"][0]["s3"]["object"]["key"]
base_filename = s3_object.rsplit(".", 1)[0]
# Launch EC2 instance
response = ec2.run_instances(
ImageId=AMI_ID,
InstanceType=INSTANCE_TYPE,
KeyName="deep_learning_instance_2",
SecurityGroupIds=[SECURITY_GROUP_ID],
MinCount=1,
MaxCount=1,
InstanceMarketOptions={
"MarketType": "spot",
"SpotOptions": {
"SpotInstanceType": "one-time",
"InstanceInterruptionBehavior": "terminate"
}
},
IamInstanceProfile={'Name': 'EC2-S3-Access'},
UserData=f'''#!/bin/bash
apt update && apt install -y ffmpeg git python3-pip
apt install -y ffmpeg git python3 python3-pip
# Instalar Whisper AI
pip3 install openai-whisper
# Instalar PyTorch con CUDA
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
aws s3 cp s3://{S3_BUCKET}/{s3_object} /home/ubuntu/{s3_object}
whisper /home/ubuntu/{base_filename}.mp3 --language Portuguese --model medium --task transcribe --output_format srt --device cuda
aws s3 cp /home/ubuntu/{base_filename}.srt s3://{S3_OUTPUT_BUCKET}/{base_filename}.srt
shutdown -h now
''',
TagSpecifications=[{
'ResourceType': 'instance',
'Tags': [{'Key': 'Purpose', 'Value': 'WhisperProcessing'}]
}]
)
instance_id = response['Instances'][0]['InstanceId']
print(f"EC2 Instance Launched: {instance_id} for file {s3_object}")
return {"message": f"Processing started for {s3_object}, EC2 instance {instance_id} launched."}
Takeaways
Después de ver una peli subtitulada con Whisper creo que es una gran opción para este caso de uso. Creo que configurar lambda para automatizar todo no vale la pena.