ruslanmv commited on
Commit
a1cb500
·
1 Parent(s): 4e09337

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +44 -42
app.py CHANGED
@@ -1,38 +1,30 @@
1
  # ---- Flags ----
2
  run_api = False
3
- SSD_1B = False
4
 
5
  # ---- Standard imports ----
6
  import os
7
  import subprocess
8
  import numpy as np
9
- from IPython.display import clear_output
10
 
11
- # ---- Minimal, deterministic env bootstrap (optional) ----
12
- # Prefer pinning in requirements.txt instead of installing here.
13
- def check_environment():
14
- try:
15
- import torch # noqa: F401
16
- print("Environment is already installed.")
17
- except ImportError:
18
- print("Environment not found. Installing pinned dependencies...")
19
- # Strongly prefer doing this via requirements.txt at build time.
20
- os.system("pip install --upgrade pip")
21
- os.system("pip install diffusers==0.30.0 transformers>=4.41.0 accelerate>=0.31.0 huggingface_hub>=0.23.4 safetensors>=0.4.2 gradio==4.37.1 python-dotenv")
22
- clear_output()
23
- print("Environment installed successfully.")
24
-
25
- check_environment()
26
-
27
- # ---- App imports (safe after environment check) ----
28
  import torch
29
  import gradio as gr
30
  from PIL import Image
31
  from diffusers import UNet2DConditionModel, DiffusionPipeline, LCMScheduler
32
 
33
- # Optional: only imported if SSD_1B=True
34
- # from diffusers import AutoPipelineForText2Image
35
-
36
  # ---- Config / constants ----
37
  current_dir = os.getcwd()
38
  cache_path = os.path.join(current_dir, "cache")
@@ -42,31 +34,37 @@ MAX_SEED = np.iinfo(np.int32).max
42
  MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "1024"))
43
  SECRET_TOKEN = os.getenv("SECRET_TOKEN", "default_secret")
44
 
45
- # ---- GPU / NVML detection (robust) ----
46
  def print_nvidia_smi():
47
  try:
48
  proc = subprocess.run(["nvidia-smi"], capture_output=True, text=True)
49
- if proc.returncode == 0:
50
  print(proc.stdout)
51
  else:
52
- # Show the stderr to aid debugging, but don't trust it for logic
53
- print(proc.stderr or "nvidia-smi returned a non-zero exit code.")
 
 
 
54
  except FileNotFoundError:
55
  print("nvidia-smi not found on PATH.")
56
 
57
  print_nvidia_smi()
58
 
 
59
  is_gpu = torch.cuda.is_available()
60
  print(f"CUDA available: {is_gpu}")
61
 
62
- # dtype & device
63
- dtype = torch.float16 if is_gpu else torch.float32
64
  device = torch.device("cuda") if is_gpu else torch.device("cpu")
 
65
 
66
- # Optional: fewer surprises when CUDA is flaky
67
- if not is_gpu:
68
- # Avoid cuda-related env flags when no GPU
69
- os.environ.pop("CUDA_LAUNCH_BLOCKING", None)
 
 
 
70
 
71
  # ---- Pipeline setup ----
72
  if not SSD_1B:
@@ -74,26 +72,26 @@ if not SSD_1B:
74
  unet = UNet2DConditionModel.from_pretrained(
75
  "latent-consistency/lcm-sdxl",
76
  torch_dtype=dtype,
77
- variant="fp16" if is_gpu else None,
78
  cache_dir=cache_path,
 
79
  )
80
  pipe = DiffusionPipeline.from_pretrained(
81
  "stabilityai/stable-diffusion-xl-base-1.0",
82
  unet=unet,
83
  torch_dtype=dtype,
84
- variant="fp16" if is_gpu else None,
85
  cache_dir=cache_path,
 
86
  )
87
  pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
88
  pipe.to(device)
89
  else:
90
  # SSD-1B + LCM LoRA
91
- from diffusers import AutoPipelineForText2Image # local import
92
  pipe = AutoPipelineForText2Image.from_pretrained(
93
  "segmind/SSD-1B",
94
  torch_dtype=dtype,
95
- variant="fp16" if is_gpu else None,
96
  cache_dir=cache_path,
 
97
  )
98
  pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
99
  pipe.to(device)
@@ -111,12 +109,15 @@ def generate(
111
  num_inference_steps: int = 4,
112
  secret_token: str = "",
113
  ) -> Image.Image:
 
114
  if secret_token != SECRET_TOKEN:
115
  raise gr.Error("Invalid secret token. Set SECRET_TOKEN on the server or pass the correct token.")
116
- # Make sure sizes are sane on CPU
 
117
  width = int(np.clip(width, 256, MAX_IMAGE_SIZE))
118
  height = int(np.clip(height, 256, MAX_IMAGE_SIZE))
119
 
 
120
  generator = torch.Generator(device=device)
121
  if seed is not None:
122
  generator = generator.manual_seed(int(seed))
@@ -133,8 +134,6 @@ def generate(
133
  )
134
  return out.images[0]
135
 
136
- clear_output()
137
-
138
  # ---- Optional notebook helper ----
139
  def generate_image(prompt="A scenic watercolor landscape, mountains at dawn"):
140
  img = generate(
@@ -147,10 +146,13 @@ def generate_image(prompt="A scenic watercolor landscape, mountains at dawn"):
147
  num_inference_steps=4,
148
  secret_token=SECRET_TOKEN,
149
  )
150
- from IPython.display import display
151
- display(img)
 
 
 
152
 
153
- # ---- UI ----
154
  if not run_api:
155
  secret_token = gr.Textbox(
156
  label="Secret Token",
 
1
  # ---- Flags ----
2
  run_api = False
3
+ SSD_1B = False # True = use SSD-1B + LCM LoRA, False = SDXL Base + LCM (default)
4
 
5
  # ---- Standard imports ----
6
  import os
7
  import subprocess
8
  import numpy as np
 
9
 
10
+ # Optional: clear_output is nice in notebooks; ignore if not available
11
+ try:
12
+ from IPython.display import clear_output # noqa: F401
13
+ except Exception:
14
+ def clear_output(): # no-op outside notebooks
15
+ pass
16
+
17
+ # ---- Tame NVML noise in containers without GPU drivers (optional) ----
18
+ os.environ.setdefault("DEEPSPEED_DISABLE_NVML", "1")
19
+ import warnings
20
+ warnings.filterwarnings("ignore", message="Can't initialize NVML")
21
+
22
+ # ---- App imports (expect deps from requirements.txt already installed) ----
 
 
 
 
23
  import torch
24
  import gradio as gr
25
  from PIL import Image
26
  from diffusers import UNet2DConditionModel, DiffusionPipeline, LCMScheduler
27
 
 
 
 
28
  # ---- Config / constants ----
29
  current_dir = os.getcwd()
30
  cache_path = os.path.join(current_dir, "cache")
 
34
  MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "1024"))
35
  SECRET_TOKEN = os.getenv("SECRET_TOKEN", "default_secret")
36
 
37
+ # ---- GPU visibility / info (for logs only) ----
38
  def print_nvidia_smi():
39
  try:
40
  proc = subprocess.run(["nvidia-smi"], capture_output=True, text=True)
41
+ if proc.returncode == 0 and proc.stdout.strip():
42
  print(proc.stdout)
43
  else:
44
+ # Show stderr when present to help debugging; not used for logic
45
+ if proc.stderr:
46
+ print(proc.stderr)
47
+ else:
48
+ print("nvidia-smi not available or returned no output.")
49
  except FileNotFoundError:
50
  print("nvidia-smi not found on PATH.")
51
 
52
  print_nvidia_smi()
53
 
54
+ # ---- Device + dtype selection (robust) ----
55
  is_gpu = torch.cuda.is_available()
56
  print(f"CUDA available: {is_gpu}")
57
 
 
 
58
  device = torch.device("cuda") if is_gpu else torch.device("cpu")
59
+ dtype = torch.float16 if is_gpu else torch.float32
60
 
61
+ # ---- Helpers to only pass 'variant' when needed (Diffusers <=0.23 friendly) ----
62
+ def _add_variant(kwargs: dict) -> dict:
63
+ """Only include 'variant' when running on GPU."""
64
+ if is_gpu:
65
+ kwargs = dict(kwargs) # shallow copy
66
+ kwargs["variant"] = "fp16"
67
+ return kwargs
68
 
69
  # ---- Pipeline setup ----
70
  if not SSD_1B:
 
72
  unet = UNet2DConditionModel.from_pretrained(
73
  "latent-consistency/lcm-sdxl",
74
  torch_dtype=dtype,
 
75
  cache_dir=cache_path,
76
+ **_add_variant({})
77
  )
78
  pipe = DiffusionPipeline.from_pretrained(
79
  "stabilityai/stable-diffusion-xl-base-1.0",
80
  unet=unet,
81
  torch_dtype=dtype,
 
82
  cache_dir=cache_path,
83
+ **_add_variant({})
84
  )
85
  pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
86
  pipe.to(device)
87
  else:
88
  # SSD-1B + LCM LoRA
89
+ from diffusers import AutoPipelineForText2Image
90
  pipe = AutoPipelineForText2Image.from_pretrained(
91
  "segmind/SSD-1B",
92
  torch_dtype=dtype,
 
93
  cache_dir=cache_path,
94
+ **_add_variant({})
95
  )
96
  pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
97
  pipe.to(device)
 
109
  num_inference_steps: int = 4,
110
  secret_token: str = "",
111
  ) -> Image.Image:
112
+ # Token gate
113
  if secret_token != SECRET_TOKEN:
114
  raise gr.Error("Invalid secret token. Set SECRET_TOKEN on the server or pass the correct token.")
115
+
116
+ # Clamp sizes (avoid OOM on CPU)
117
  width = int(np.clip(width, 256, MAX_IMAGE_SIZE))
118
  height = int(np.clip(height, 256, MAX_IMAGE_SIZE))
119
 
120
+ # Deterministic generator on the active device
121
  generator = torch.Generator(device=device)
122
  if seed is not None:
123
  generator = generator.manual_seed(int(seed))
 
134
  )
135
  return out.images[0]
136
 
 
 
137
  # ---- Optional notebook helper ----
138
  def generate_image(prompt="A scenic watercolor landscape, mountains at dawn"):
139
  img = generate(
 
146
  num_inference_steps=4,
147
  secret_token=SECRET_TOKEN,
148
  )
149
+ try:
150
+ from IPython.display import display
151
+ display(img)
152
+ except Exception:
153
+ pass # Non-notebook environment
154
 
155
+ # ---- UI (Gradio 3.39.0 components) ----
156
  if not run_api:
157
  secret_token = gr.Textbox(
158
  label="Secret Token",