lea97338 commited on
Commit
3fbf886
·
verified ·
1 Parent(s): 61df69c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -130
app.py CHANGED
@@ -1,143 +1,55 @@
1
- import gc
2
- import os
3
- import io
4
- import time
5
- import tempfile
6
- import logging
7
- import spaces
8
-
9
  import torch
10
  import gradio as gr
11
- from transformers import AutoTokenizer, AutoModelForCausalLM
12
-
13
- from dd import encode_prompt # <-- version Qwen compatible
14
-
15
- # ------------------------------------------------------
16
- # Logging
17
- # ------------------------------------------------------
18
- logging.basicConfig(
19
- level=os.getenv("LOG_LEVEL", "INFO"),
20
- format="%(asctime)s [%(levelname)s] %(name)s - %(message)s",
21
- )
22
- logger = logging.getLogger("qwen-text-encoding-gradio")
23
-
24
- # ------------------------------------------------------
25
- # Config
26
- # ------------------------------------------------------
27
- TEXT_ENCODER_ID = "Qwen/Qwen2.5-0.5B-Instruct"
28
- TOKENIZER_ID = "Qwen/Qwen2.5-0.5B-Instruct"
29
- DTYPE = torch.float32 # CPU safe
30
-
31
- # ------------------------------------------------------
32
- # Load model
33
- # ------------------------------------------------------
34
- logger.info("Loading Qwen 0.5B...")
35
-
36
- t0 = time.time()
37
- text_encoder = AutoModelForCausalLM.from_pretrained(
38
- TEXT_ENCODER_ID,
39
- torch_dtype=DTYPE,
40
- low_cpu_mem_usage=True,
41
- ).to("cpu")
42
-
43
- t1 = time.time()
44
- tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_ID)
45
-
46
- logger.info("Loaded Qwen in %.2fs", time.time() - t0)
47
- torch.set_grad_enabled(False)
48
-
49
-
50
- def get_vram_info():
51
- if torch.cuda.is_available():
52
- return {
53
- "vram_allocated_mb": round(torch.cuda.memory_allocated() / 1024 / 1024, 2),
54
- "vram_reserved_mb": round(torch.cuda.memory_reserved() / 1024 / 1024, 2),
55
- "vram_max_allocated_mb": round(torch.cuda.max_memory_allocated() / 1024 / 1024, 2),
56
- }
57
- return {"vram": "CUDA not available"}
58
-
59
-
60
- @spaces.GPU()
61
- def encode_text(prompt: str):
62
- """Encode text and return a downloadable pytorch file."""
63
- global text_encoder, tokenizer
64
-
65
- if text_encoder is None or tokenizer is None:
66
- return None, "Model not loaded"
67
-
68
- t0 = time.time()
69
-
70
- # Multi‑prompts support
71
- prompts = [p.strip() for p in prompt.strip().split("\n") if p.strip()]
72
- if not prompts:
73
- return None, "Please enter at least one prompt"
74
-
75
- num_prompts = len(prompts)
76
- prompt_input = prompts[0] if num_prompts == 1 else prompts
77
-
78
- logger.info("Encoding %d prompt(s)", num_prompts)
79
-
80
- # 🔥 Qwen‑compatible encode_prompt (dd.py)
81
- prompt_embeds, text_ids = encode_prompt(
82
- text_encoder=text_encoder,
83
- tokenizer=tokenizer,
84
- prompt=prompt_input,
85
  )
86
 
87
- duration = (time.time() - t0) * 1000.0
88
- logger.info(
89
- "Encoded in %.2f ms | prompt_embeds.shape=%s | text_ids.shape=%s",
90
- duration,
91
- tuple(prompt_embeds.shape),
92
- tuple(text_ids.shape),
93
- )
94
-
95
- # Save tensor
96
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".pt")
97
- torch.save(prompt_embeds.cpu(), temp_file.name)
98
-
99
- # Cleanup
100
- del prompt_embeds, text_ids
101
- gc.collect()
102
- if torch.cuda.is_available():
103
- torch.cuda.empty_cache()
104
 
105
- vram = get_vram_info()
106
- status = (
107
- f"Encoded {num_prompts} prompt(s) in {duration:.2f}ms\n"
108
- f"VRAM: {vram.get('vram_allocated_mb', 'N/A')} MB allocated, "
109
- f"{vram.get('vram_max_allocated_mb', 'N/A')} MB peak"
110
- )
111
 
112
- return temp_file.name, status
113
 
 
 
 
 
 
114
 
115
- # ------------------------------------------------------
116
- # Gradio Interface
117
- # ------------------------------------------------------
118
- with gr.Blocks(title="Qwen Text Encoder") as demo:
119
- gr.Markdown("# Qwen 2.5 Text Encoder")
120
- gr.Markdown("Enter text to encode. For multiple prompts, put each on a new line.")
121
 
122
- with gr.Row():
123
- with gr.Column():
124
- prompt_input = gr.Textbox(
125
- label="Prompt(s)",
126
- placeholder="Enter your prompt here...\nOr multiple prompts, one per line",
127
- lines=5,
128
- )
129
- encode_btn = gr.Button("Encode", variant="primary")
130
 
131
- with gr.Column():
132
- output_file = gr.File(label="Download Embeddings (.pt)")
133
- status_output = gr.Textbox(label="Status", interactive=False)
134
 
135
- encode_btn.click(
136
- fn=encode_text,
137
- inputs=[prompt_input],
138
- outputs=[output_file, status_output],
139
- )
140
 
 
 
 
 
 
 
 
 
 
 
141
 
142
- if __name__ == "__main__":
143
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
 
 
 
 
1
  import torch
2
  import gradio as gr
3
+ from diffusers import Flux2Pipeline
4
+
5
+ # -----------------------------
6
+ # ENCODEUR FLUX MINIMAL
7
+ # -----------------------------
8
+ def encode_prompt(prompt: str):
9
+ # On charge uniquement le tokenizer + text_encoder
10
+ pipe = Flux2Pipeline.from_pretrained(
11
+ "black-forest-labs/FLUX.2-klein-4B",
12
+ torch_dtype=torch.float32,
13
+ low_cpu_mem_usage=True,
14
+
15
+ # 🔥 On désactive tout ce qui n'est PAS utilisé par encode_prompt()
16
+ transformer=None, # pas besoin du modèle de diffusion
17
+ vae=None, # pas besoin pour encoder du texte
18
+ scheduler=None, # inutile
19
+ safety_checker=None, # inutile
20
+ feature_extractor=None, # inutile
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  )
22
 
23
+ with torch.inference_mode():
24
+ prompt_embeds = pipe.encode_prompt(prompt)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
+ return prompt_embeds
 
 
 
 
 
27
 
 
28
 
29
+ # -----------------------------
30
+ # FONCTION GRADIO
31
+ # -----------------------------
32
+ def run_encoder(prompt):
33
+ embeds = encode_prompt(prompt)
34
 
35
+ # On renvoie la forme pour vérifier
36
+ shape = tuple(embeds.shape)
 
 
 
 
37
 
38
+ # On sauvegarde pour un autre Space si besoin
39
+ torch.save(embeds.cpu(), "embeds.pt")
 
 
 
 
 
 
40
 
41
+ return f"Embeddings générés : shape = {shape}"
 
 
42
 
 
 
 
 
 
43
 
44
+ # -----------------------------
45
+ # INTERFACE GRADIO
46
+ # -----------------------------
47
+ demo = gr.Interface(
48
+ fn=run_encoder,
49
+ inputs=gr.Textbox(label="Prompt", placeholder="Écris ton texte ici..."),
50
+ outputs=gr.Textbox(label="Résultat"),
51
+ title="Encodeur Texte FLUX.2 — Version Minimaliste",
52
+ description="Génère les embeddings texte officiels de FLUX.2 sans charger le VAE ou le modèle de diffusion.",
53
+ )
54
 
55
+ demo.launch()