ZHSAPI / main.py
clove1002's picture
Fallback to CPU FILM interpolation when GPU quota exceeded
7287532
Raw
History Blame Contribute Delete
2.31 kB
from fastapi import FastAPI, UploadFile, File, Form
from fastapi.responses import FileResponse, JSONResponse
from gradio_client import Client, handle_file
from gradio_client.exceptions import AppError
import tempfile
import os
import shutil
HF_TOKEN = os.getenv("HF_TOKEN")
app = FastAPI(title="ZHSAPI")
@app.get("/health")
def health():
return {"status": "ok"}
@app.post("/timelapse")
async def generate_timelapse(
start_frame: UploadFile = File(...),
end_frame: UploadFile = File(...),
prompt: str = Form(default="a construction timelapse"),
):
with tempfile.TemporaryDirectory() as tmpdir:
start_path = os.path.join(tmpdir, start_frame.filename)
end_path = os.path.join(tmpdir, end_frame.filename)
with open(start_path, "wb") as f:
shutil.copyfileobj(start_frame.file, f)
with open(end_path, "wb") as f:
shutil.copyfileobj(end_frame.file, f)
# Try diffusion model first, fall back to CPU FILM interpolation on quota error
try:
client = Client("linoyts/LTX-2-3-First-Last-Frame", token=HF_TOKEN)
result = client.predict(
first_image=handle_file(start_path),
last_image=handle_file(end_path),
input_audio=None,
prompt=prompt,
api_name="/generate_video",
)
output_path = result[0] if isinstance(result, (list, tuple)) else result
except AppError as e:
if "GPU quota" not in str(e):
return JSONResponse(status_code=502, content={"error": str(e)})
# Fallback: CPU-based FILM interpolation (no GPU quota)
film = Client("freealise/video_frame_interpolation")
loaded = film.predict(
f=[handle_file(start_path), handle_file(end_path)],
r_bg=False,
api_name="/loadf",
)
frames = loaded[0]
result = film.predict(
f_in=frames,
interpolation=4,
fps_output=0,
api_name="/infer",
)
output_path = result[0]["video"] if isinstance(result[0], dict) else result[0]
return FileResponse(output_path, media_type="video/mp4", filename="timelapse.mp4")