redkits commited on
Commit
dcb6cc1
·
verified ·
1 Parent(s): 77a6e14

Upload server.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. server.py +86 -0
server.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import subprocess
4
+ import base64
5
+ import io
6
+ import json
7
+
8
+ # Install diffusers from source (supports WanPipeline)
9
+ subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "git+https://github.com/huggingface/diffusers.git"])
10
+ subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "accelerate", "sentencepiece", "protobuf", "imageio[ffmpeg]"])
11
+
12
+ import torch
13
+ from flask import Flask, request, jsonify
14
+ from diffusers import AutoencoderKLWan, WanPipeline
15
+ from diffusers.utils import export_to_video
16
+
17
+ app = Flask(__name__)
18
+ pipe = None
19
+
20
+ def load_model():
21
+ global pipe
22
+ print("[video] Loading Wan2.2-TI2V-5B pipeline...", flush=True)
23
+ vae = AutoencoderKLWan.from_pretrained(
24
+ "Wan-AI/Wan2.2-TI2V-5B-Diffusers",
25
+ subfolder="vae",
26
+ torch_dtype=torch.float32,
27
+ )
28
+ pipe = WanPipeline.from_pretrained(
29
+ "Wan-AI/Wan2.2-TI2V-5B-Diffusers",
30
+ vae=vae,
31
+ torch_dtype=torch.bfloat16,
32
+ )
33
+ pipe.to("cuda")
34
+ print("[video] Model loaded successfully!", flush=True)
35
+
36
+ @app.route("/health", methods=["GET"])
37
+ def health():
38
+ if pipe is not None:
39
+ return jsonify({"status": "healthy"}), 200
40
+ return jsonify({"status": "loading"}), 503
41
+
42
+ @app.route("/", methods=["POST"])
43
+ def generate():
44
+ try:
45
+ data = request.get_json()
46
+ prompt = data.get("inputs", "")
47
+ params = data.get("parameters", {})
48
+
49
+ num_frames = int(params.get("num_frames", 49))
50
+ height = int(params.get("height", 480))
51
+ width = int(params.get("width", 832))
52
+ steps = int(params.get("num_inference_steps", 30))
53
+ fps = int(params.get("fps", 24))
54
+ guidance = float(params.get("guidance_scale", 5.0))
55
+ negative = params.get("negative_prompt", "low quality, blurry, distorted")
56
+
57
+ print(f"[video] Generating {num_frames} frames: {prompt[:100]}...", flush=True)
58
+ frames = pipe(
59
+ prompt=prompt,
60
+ negative_prompt=negative,
61
+ num_frames=num_frames,
62
+ height=height,
63
+ width=width,
64
+ num_inference_steps=steps,
65
+ guidance_scale=guidance,
66
+ ).frames[0]
67
+
68
+ buf = io.BytesIO()
69
+ export_to_video(frames, buf, fps=fps)
70
+ video_b64 = base64.b64encode(buf.getvalue()).decode("utf-8")
71
+ duration = len(frames) / fps
72
+ print(f"[video] Done, {len(frames)} frames, {duration:.1f}s", flush=True)
73
+
74
+ return jsonify({
75
+ "video": video_b64,
76
+ "format": "mp4",
77
+ "frames": len(frames),
78
+ "duration": duration,
79
+ })
80
+ except Exception as e:
81
+ print(f"[video] Error: {e}", flush=True)
82
+ return jsonify({"error": str(e)}), 500
83
+
84
+ if __name__ == "__main__":
85
+ load_model()
86
+ app.run(host="0.0.0.0", port=8000)