tuan2308 commited on
Commit
51dd78a
·
verified ·
1 Parent(s): 21be370

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +94 -0
app.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import spaces
4
+ from transformers import AutoProcessor, Qwen2VLForConditionalGeneration
5
+ from PIL import Image
6
+
7
+ BASE_MODEL = "Qwen/Qwen2-VL-2B-Instruct"
8
+ BFS_MODEL = "Alissonerdx/BFS-Best-Face-Swap"
9
+
10
+ # ----------- FORCE CPU FOR ZERO-GPU -----------
11
+ DEVICE = "cpu"
12
+ DTYPE = torch.float32
13
+
14
+ print("Using device:", DEVICE)
15
+
16
+ # ----------- LOAD BASE MODEL -----------
17
+ print("Loading Qwen2-VL base model (CPU, FP32)...")
18
+ model = Qwen2VLForConditionalGeneration.from_pretrained(
19
+ BASE_MODEL,
20
+ dtype=DTYPE,
21
+ device_map=None
22
+ )
23
+
24
+ model.to(DEVICE)
25
+
26
+ processor = AutoProcessor.from_pretrained(BASE_MODEL)
27
+
28
+ # ----------- LOAD BFS ADAPTERS -----------
29
+ ADAPTERS = {
30
+ "face_v1": f"{BFS_MODEL}/bfs_face_v1.bin",
31
+ "head_v1": f"{BFS_MODEL}/bfs_head_v1.bin",
32
+ "head_v2": f"{BFS_MODEL}/bfs_head_v2.bin",
33
+ "head_v3": f"{BFS_MODEL}/bfs_head_v3.bin",
34
+ }
35
+
36
+ adapter_states = {
37
+ k: torch.load(path, map_location=DEVICE)
38
+ for k, path in ADAPTERS.items()
39
+ }
40
+
41
+ @spaces.GPU
42
+ def apply_adapter(model, adapter_state):
43
+ print("Applying adapter:", len(adapter_state))
44
+ model.load_state_dict(adapter_state, strict=False)
45
+
46
+
47
+ def bfs_swap(img1, img2, version):
48
+ if img1 is None or img2 is None:
49
+ return None
50
+
51
+ apply_adapter(model, adapter_states[version])
52
+
53
+ prompt = "swap the face of img1 onto img2, realistic, high quality"
54
+
55
+ inputs = processor(
56
+ text=prompt,
57
+ images=[img1, img2],
58
+ return_tensors="pt"
59
+ ).to(DEVICE)
60
+
61
+ out = model.generate(
62
+ **inputs,
63
+ max_new_tokens=1,
64
+ do_sample=False
65
+ )
66
+
67
+ decoded = processor.decode(out[0], skip_special_tokens=True)
68
+
69
+ if isinstance(decoded, dict) and "image" in decoded:
70
+ return decoded["image"]
71
+
72
+ return None
73
+
74
+
75
+ with gr.Blocks() as demo:
76
+ gr.Markdown("## BFS Best Face Swap (Qwen2-VL 2B — CPU Mode for ZeroGPU)")
77
+
78
+ img1 = gr.Image(type="pil", label="Image 1")
79
+ img2 = gr.Image(type="pil", label="Image 2")
80
+
81
+ version = gr.Radio(
82
+ ["face_v1", "head_v1", "head_v2", "head_v3"],
83
+ label="Choose Version"
84
+ )
85
+
86
+ result = gr.Image(label="Output")
87
+
88
+ gr.Button("Swap!").click(
89
+ bfs_swap,
90
+ inputs=[img1, img2, version],
91
+ outputs=result
92
+ )
93
+
94
+ demo.launch()