Files
6800xt-100/optimized_gpu_pipeline.py
renato97 5a47060f04 Initial commit: 100% GPU pipeline for AMD 6800 XT
- OpenAI Whisper with ROCm GPU support
- VAAPI decode + encode (no CPU fallback)
- Achieves 98-99% GPU usage during transcription
- Designed for AMD GPUs with ROCm 7.1
2026-02-20 00:13:04 -03:00

168 lines
4.6 KiB
Python

#!/usr/bin/env python3
"""
OPTIMIZED GPU PIPELINE - 100% GPU for AMD with ROCm
Uses: OpenAI Whisper (ROCm) + VAAPI decode/encode
"""
import torch
import json
import subprocess
import os
import re
import whisper
VIDEO = "/home/ren/Documents/proyecto_2026/Twitch-Highlight-Detector/20260219_205705_twitch.mp4"
OUTPUT_DIR = "/home/ren/Documents/proyecto_2026/Twitch-Highlight-Detector"
VADEVICE = "/dev/dri/renderD128"
print("=" * 60)
print("OPTIMIZED GPU PIPELINE - 100% AMD GPU")
print("=" * 60)
if torch.cuda.is_available():
print(f"GPU: {torch.cuda.get_device_name(0)}")
print(f"VRAM: {torch.cuda.get_device_properties(0).total_memory / 1024**3:.1f} GB")
# =====================
# STEP 1: OpenAI Whisper (ROCm GPU)
# =====================
print("\n[1/4] Transcription with Whisper on ROCm GPU...")
transcription_file = f"{OUTPUT_DIR}/transcripcion.json"
if os.path.exists(transcription_file):
with open(transcription_file) as f:
transcription = json.load(f)
print(f" Loaded {len(transcription.get('segments', []))} segments from cache")
else:
print(" Loading Whisper small on ROCm GPU...")
model = whisper.load_model("small", device="cuda")
print(" Transcribing on GPU...")
result = model.transcribe(
VIDEO,
language="es",
temperature=0.0
)
transcription = {
'segments': [{'start': s['start'], 'end': s['end'], 'text': s['text']} for s in result['segments']]
}
with open(transcription_file, 'w') as f:
json.dump(transcription, f)
print(f" Done: {len(transcription['segments'])} segments")
# =====================
# STEP 2: Analysis (minimal CPU)
# =====================
print("\n[2/4] Analysis...")
patterns = {
'rage': re.compile(r'put[a-z]*|coño|mierda|hostia|joder|carajo|pendejo', re.I),
'epic': re.compile(r'kill|matar|muerte|pelea|baron|dragon', re.I),
}
valid = []
for t in transcription.get('segments', []):
if t.get('start', 0) > 420 and len(t.get('text', '')) > 10:
text = t.get('text', '').lower()
if 'dior' not in text:
score = 0
for p in patterns.values():
if p.search(text):
score += 15
if score > 0:
valid.append({
'start': int(t['start']) - 10,
'end': int(t['end']) + 20,
'score': score
})
valid.sort(key=lambda x: x['score'], reverse=True)
filtered = []
for v in valid:
if not filtered or v['start'] - filtered[-1]['end'] > 40:
filtered.append(v)
filtered = filtered[:20]
print(f" Highlights: {len(filtered)}")
# =====================
# STEP 3: GPU Encoding (VAAPI decode + encode)
# =====================
print("\n[3/4] GPU Encoding (VAAPI decode + encode)...")
def encode_clip(i, h):
output = f"{OUTPUT_DIR}/opt_clip_{i}.mp4"
start = h['start']
duration = min(h['end'] - h['start'], 60)
cmd = [
'ffmpeg', '-y',
'-hwaccel', 'vaapi',
'-hwaccel_device', VADEVICE,
'-hwaccel_output_format', 'vaapi',
'-i', VIDEO,
'-ss', str(start),
'-t', str(duration),
'-vf', 'scale_vaapi=1920:1080:format=nv12',
'-c:v', 'h264_vaapi',
'-b:v', '5M',
'-c:a', 'aac', '-b:a', '128k',
output
]
result = subprocess.run(cmd, capture_output=True)
if os.path.exists(output) and os.path.getsize(output) > 1000:
print(f" Clip {i} done (VAAPI GPU)")
return output
stderr = result.stderr.decode()[-300:] if result.stderr else "no error"
print(f" Clip {i} VAAPI failed: {stderr}")
return None
clips = []
for i, h in enumerate(filtered):
result = encode_clip(i, h)
if result:
clips.append(result)
print(f" Encoded {len(clips)} clips on GPU")
# =====================
# STEP 4: Concatenate
# =====================
print("\n[4/4] Concatenating...")
if not clips:
print(" No clips to concatenate!")
exit(1)
concat_file = f"{OUTPUT_DIR}/concat_opt.txt"
with open(concat_file, 'w') as f:
for clip in clips:
f.write(f"file '{clip}'\n")
output = f"{OUTPUT_DIR}/HIGHLIGHTS_OPT.mp4"
cmd = [
'ffmpeg', '-y',
'-f', 'concat', '-safe', '0', '-i', concat_file,
'-c', 'copy',
output
]
subprocess.run(cmd, capture_output=True)
# Cleanup
for c in clips:
if os.path.exists(c):
os.remove(c)
if os.path.exists(concat_file):
os.remove(concat_file)
if os.path.exists(output):
size = os.path.getsize(output) / 1024 / 1024
print(f"\n✅ DONE! {output} ({size:.1f} MB)")
else:
print("ERROR creating final file!")