Suporte commited on
Commit
8d1717c
·
1 Parent(s): dfafb32

Setup unsloth FLUX.2-klein-base-4B-GGUF local CPU Basic app

Browse files
Files changed (3) hide show
  1. README.md +6 -4
  2. app.py +63 -36
  3. requirements.txt +3 -2
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: Local Image Edit CPU Basic
3
  colorFrom: gray
4
  colorTo: blue
5
  sdk: gradio
@@ -8,9 +8,11 @@ app_file: app.py
8
  pinned: false
9
  ---
10
 
11
- Space configurado para executar a edicao de imagem localmente no proprio CPU Basic.
 
12
 
13
  Notas:
14
  - Sem uso de Inference Providers remotos.
15
- - Primeira execucao pode demorar por download e load do modelo.
16
- - Se falhar por memoria/tempo, reduz o tamanho da imagem de entrada.
 
 
1
  ---
2
+ title: FLUX.2-klein-base-4B-GGUF CPU Basic
3
  colorFrom: gray
4
  colorTo: blue
5
  sdk: gradio
 
8
  pinned: false
9
  ---
10
 
11
+ Space configurado para executar localmente no CPU Basic com:
12
+ `unsloth/FLUX.2-klein-base-4B-GGUF`
13
 
14
  Notas:
15
  - Sem uso de Inference Providers remotos.
16
+ - Primeira execucao demora (download + load do GGUF).
17
+ - Default usa `flux-2-klein-base-4b-Q2_K.gguf` para reduzir RAM.
18
+ - Se falhar, reduz imagem e steps.
app.py CHANGED
@@ -1,19 +1,22 @@
1
  import os
 
2
  import threading
3
 
4
  import gradio as gr
5
  import torch
6
- from diffusers import StableDiffusionInstructPix2PixPipeline, EulerAncestralDiscreteScheduler
 
7
  from PIL import Image
8
 
9
- MODEL_ID = os.getenv("MODEL_ID", "timbrooks/instruct-pix2pix")
 
 
10
  MAX_SIDE = int(os.getenv("MAX_SIDE", "768"))
11
- NUM_STEPS = int(os.getenv("NUM_STEPS", "18"))
12
- GUIDANCE_SCALE = float(os.getenv("GUIDANCE_SCALE", "7.0"))
13
- IMAGE_GUIDANCE_SCALE = float(os.getenv("IMAGE_GUIDANCE_SCALE", "1.5"))
14
 
15
  _pipe = None
16
- _pipe_err = None
17
  _lock = threading.Lock()
18
 
19
 
@@ -23,72 +26,96 @@ def _prepare_image(img: Image.Image) -> Image.Image:
23
  m = max(w, h)
24
  if m > MAX_SIDE:
25
  s = MAX_SIDE / m
26
- w, h = int(w * s), int(h * s)
27
- w = max(64, (w // 8) * 8)
28
- h = max(64, (h // 8) * 8)
 
29
  return img.resize((w, h), Image.Resampling.LANCZOS)
30
 
31
 
32
- def get_pipe() -> StableDiffusionInstructPix2PixPipeline:
33
- global _pipe, _pipe_err
34
- if _pipe_err:
35
- raise RuntimeError(_pipe_err)
36
  if _pipe is None:
37
  with _lock:
38
  if _pipe is None:
39
  try:
40
- pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained(
41
- MODEL_ID,
 
 
 
42
  torch_dtype=torch.float32,
43
- safety_checker=None,
44
  )
45
- pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
 
 
 
 
 
46
  pipe.set_progress_bar_config(disable=True)
47
  pipe.enable_attention_slicing()
48
- pipe = pipe.to("cpu")
 
49
  _pipe = pipe
50
  except Exception as e:
51
- _pipe_err = str(e)
52
  raise
53
  return _pipe
54
 
55
 
56
- def edit_image(image: Image.Image, prompt: str):
57
- if image is None:
58
- raise gr.Error("Carrega uma imagem primeiro.")
59
  if not prompt or not prompt.strip():
60
- raise gr.Error("Escreve a instrução de edição.")
61
 
62
  try:
63
  pipe = get_pipe()
64
  except Exception:
65
- raise gr.Error("Falha ao carregar o modelo local no CPU Basic.")
 
 
 
 
 
 
 
 
 
 
 
66
 
67
- src = _prepare_image(image)
68
  try:
69
  out = pipe(
70
  prompt=prompt.strip(),
71
  image=src,
72
- num_inference_steps=NUM_STEPS,
73
- guidance_scale=GUIDANCE_SCALE,
74
- image_guidance_scale=IMAGE_GUIDANCE_SCALE,
 
 
75
  ).images[0]
76
  return out
77
  except Exception:
78
- raise gr.Error("Falha durante a geração no CPU Basic. Tenta imagem menor.")
79
 
80
 
81
  with gr.Blocks() as demo:
82
- gr.Markdown("# Image Edit local no CPU Basic")
83
- gr.Markdown("Sem Inference Providers externos. Primeira execução pode demorar no download/load.")
 
 
 
 
84
 
 
85
  with gr.Row():
86
- input_img = gr.Image(type="pil", label="Imagem")
87
- output_img = gr.Image(type="pil", label="Resultado")
 
88
 
89
- prompt = gr.Textbox(lines=3, label="Instrução")
90
- run = gr.Button("Editar")
91
- run.click(edit_image, inputs=[input_img, prompt], outputs=output_img)
92
 
93
 
94
  if __name__ == "__main__":
 
1
  import os
2
+ import random
3
  import threading
4
 
5
  import gradio as gr
6
  import torch
7
+ from diffusers import Flux2KleinPipeline, Flux2Transformer2DModel, GGUFQuantizationConfig
8
+ from huggingface_hub import hf_hub_download
9
  from PIL import Image
10
 
11
+ GGUF_REPO = "unsloth/FLUX.2-klein-base-4B-GGUF"
12
+ BASE_REPO = "black-forest-labs/FLUX.2-klein-base-4B"
13
+ GGUF_FILE = os.getenv("GGUF_FILE", "flux-2-klein-base-4b-Q2_K.gguf")
14
  MAX_SIDE = int(os.getenv("MAX_SIDE", "768"))
15
+ DEFAULT_STEPS = int(os.getenv("DEFAULT_STEPS", "8"))
16
+ DEFAULT_GUIDANCE = float(os.getenv("DEFAULT_GUIDANCE", "3.5"))
 
17
 
18
  _pipe = None
19
+ _pipe_error = None
20
  _lock = threading.Lock()
21
 
22
 
 
26
  m = max(w, h)
27
  if m > MAX_SIDE:
28
  s = MAX_SIDE / m
29
+ w = int(w * s)
30
+ h = int(h * s)
31
+ w = max(256, (w // 32) * 32)
32
+ h = max(256, (h // 32) * 32)
33
  return img.resize((w, h), Image.Resampling.LANCZOS)
34
 
35
 
36
+ def get_pipe() -> Flux2KleinPipeline:
37
+ global _pipe, _pipe_error
38
+ if _pipe_error is not None:
39
+ raise RuntimeError(_pipe_error)
40
  if _pipe is None:
41
  with _lock:
42
  if _pipe is None:
43
  try:
44
+ gguf_path = hf_hub_download(repo_id=GGUF_REPO, filename=GGUF_FILE)
45
+ qconfig = GGUFQuantizationConfig(compute_dtype=torch.float32)
46
+ transformer = Flux2Transformer2DModel.from_single_file(
47
+ gguf_path,
48
+ quantization_config=qconfig,
49
  torch_dtype=torch.float32,
 
50
  )
51
+ pipe = Flux2KleinPipeline.from_pretrained(
52
+ BASE_REPO,
53
+ transformer=transformer,
54
+ torch_dtype=torch.float32,
55
+ )
56
+ pipe = pipe.to("cpu")
57
  pipe.set_progress_bar_config(disable=True)
58
  pipe.enable_attention_slicing()
59
+ if hasattr(pipe, "enable_vae_slicing"):
60
+ pipe.enable_vae_slicing()
61
  _pipe = pipe
62
  except Exception as e:
63
+ _pipe_error = str(e)
64
  raise
65
  return _pipe
66
 
67
 
68
+ def run_edit(image: Image.Image, prompt: str, steps: int, guidance: float, seed: int):
 
 
69
  if not prompt or not prompt.strip():
70
+ raise gr.Error("Escreve uma instrucao.")
71
 
72
  try:
73
  pipe = get_pipe()
74
  except Exception:
75
+ raise gr.Error("Falha ao carregar FLUX.2-klein-base-4B-GGUF no CPU Basic.")
76
+
77
+ src = _prepare_image(image) if image is not None else None
78
+ if src is not None:
79
+ width, height = src.size
80
+ else:
81
+ width, height = 768, 768
82
+
83
+ if seed < 0:
84
+ seed = random.randint(0, 2**31 - 1)
85
+
86
+ generator = torch.Generator(device="cpu").manual_seed(seed)
87
 
 
88
  try:
89
  out = pipe(
90
  prompt=prompt.strip(),
91
  image=src,
92
+ height=height,
93
+ width=width,
94
+ num_inference_steps=max(1, int(steps)),
95
+ guidance_scale=float(guidance),
96
+ generator=generator,
97
  ).images[0]
98
  return out
99
  except Exception:
100
+ raise gr.Error("Falha na geracao. Tenta imagem menor e menos steps.")
101
 
102
 
103
  with gr.Blocks() as demo:
104
+ gr.Markdown("# FLUX.2-klein-base-4B-GGUF local (CPU Basic)")
105
+ gr.Markdown("Modelo: unsloth/FLUX.2-klein-base-4B-GGUF (Q2_K por default).")
106
+
107
+ with gr.Row():
108
+ inp = gr.Image(type="pil", label="Imagem (opcional)")
109
+ out = gr.Image(type="pil", label="Resultado")
110
 
111
+ prompt = gr.Textbox(lines=3, label="Instrucao")
112
  with gr.Row():
113
+ steps = gr.Slider(minimum=1, maximum=20, value=DEFAULT_STEPS, step=1, label="Steps")
114
+ guidance = gr.Slider(minimum=1.0, maximum=8.0, value=DEFAULT_GUIDANCE, step=0.1, label="Guidance")
115
+ seed = gr.Number(value=-1, label="Seed (-1 aleatorio)")
116
 
117
+ run_btn = gr.Button("Gerar")
118
+ run_btn.click(run_edit, inputs=[inp, prompt, steps, guidance, seed], outputs=out)
 
119
 
120
 
121
  if __name__ == "__main__":
requirements.txt CHANGED
@@ -2,8 +2,9 @@
2
 
3
  gradio==5.29.1
4
  torch==2.5.1+cpu
5
- diffusers>=0.35.0
6
- transformers>=4.46.0,<5
7
  accelerate>=1.0.0
8
  safetensors>=0.4.5
 
9
  Pillow>=10.0.0
 
2
 
3
  gradio==5.29.1
4
  torch==2.5.1+cpu
5
+ diffusers>=0.38.0
6
+ transformers>=4.57.0,<5
7
  accelerate>=1.0.0
8
  safetensors>=0.4.5
9
+ gguf>=0.13.0
10
  Pillow>=10.0.0