Spaces:
Sleeping
Sleeping
Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -22,12 +22,27 @@ CELL_TYPES = {
|
|
| 22 |
|
| 23 |
CELL_TYPE_LIST = list(CELL_TYPES.keys())
|
| 24 |
|
| 25 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
pipe = None
|
| 27 |
|
| 28 |
|
| 29 |
def load_pipeline():
|
| 30 |
-
"""Load pipeline (
|
| 31 |
global pipe
|
| 32 |
if pipe is not None:
|
| 33 |
return pipe
|
|
@@ -52,10 +67,7 @@ def load_pipeline():
|
|
| 52 |
)
|
| 53 |
pipe.unet = unet
|
| 54 |
|
| 55 |
-
# Use DPM solver for faster inference
|
| 56 |
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
|
| 57 |
-
|
| 58 |
-
# Move to CUDA (ZeroGPU will handle GPU allocation)
|
| 59 |
pipe = pipe.to("cuda")
|
| 60 |
|
| 61 |
print("Pipeline ready!")
|
|
@@ -67,15 +79,12 @@ def generate(cell_type, custom_prompt, cfg, steps, seed):
|
|
| 67 |
"""Generate a blood cell image. GPU is allocated for this function."""
|
| 68 |
pipeline = load_pipeline()
|
| 69 |
|
| 70 |
-
# Determine prompt
|
| 71 |
prompt = custom_prompt.strip() if custom_prompt and custom_prompt.strip() else CELL_TYPES.get(cell_type, CELL_TYPES["Neutrophil"])
|
| 72 |
|
| 73 |
-
# Set seed
|
| 74 |
generator = torch.Generator(device="cuda")
|
| 75 |
if int(seed) >= 0:
|
| 76 |
generator.manual_seed(int(seed))
|
| 77 |
|
| 78 |
-
# Generate
|
| 79 |
result = pipeline(
|
| 80 |
prompt=prompt,
|
| 81 |
height=512,
|
|
@@ -89,23 +98,84 @@ def generate(cell_type, custom_prompt, cfg, steps, seed):
|
|
| 89 |
|
| 90 |
|
| 91 |
# Build interface
|
| 92 |
-
with gr.Blocks() as demo:
|
| 93 |
-
gr.Markdown("
|
| 94 |
-
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
with gr.Row():
|
| 98 |
-
with gr.Column():
|
| 99 |
-
cell_dropdown = gr.Dropdown(
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
|
| 111 |
demo.launch()
|
|
|
|
| 22 |
|
| 23 |
CELL_TYPE_LIST = list(CELL_TYPES.keys())
|
| 24 |
|
| 25 |
+
# Custom CSS for soft red theme
|
| 26 |
+
custom_css = """
|
| 27 |
+
.primary-btn {
|
| 28 |
+
background: linear-gradient(135deg, #e57373 0%, #d32f2f 100%) !important;
|
| 29 |
+
border: none !important;
|
| 30 |
+
}
|
| 31 |
+
.primary-btn:hover {
|
| 32 |
+
background: linear-gradient(135deg, #ef5350 0%, #c62828 100%) !important;
|
| 33 |
+
}
|
| 34 |
+
.gradio-container {
|
| 35 |
+
max-width: 900px !important;
|
| 36 |
+
margin: auto !important;
|
| 37 |
+
}
|
| 38 |
+
"""
|
| 39 |
+
|
| 40 |
+
# Global pipeline
|
| 41 |
pipe = None
|
| 42 |
|
| 43 |
|
| 44 |
def load_pipeline():
|
| 45 |
+
"""Load pipeline (moved to GPU by @spaces.GPU decorator)."""
|
| 46 |
global pipe
|
| 47 |
if pipe is not None:
|
| 48 |
return pipe
|
|
|
|
| 67 |
)
|
| 68 |
pipe.unet = unet
|
| 69 |
|
|
|
|
| 70 |
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
|
|
|
|
|
|
|
| 71 |
pipe = pipe.to("cuda")
|
| 72 |
|
| 73 |
print("Pipeline ready!")
|
|
|
|
| 79 |
"""Generate a blood cell image. GPU is allocated for this function."""
|
| 80 |
pipeline = load_pipeline()
|
| 81 |
|
|
|
|
| 82 |
prompt = custom_prompt.strip() if custom_prompt and custom_prompt.strip() else CELL_TYPES.get(cell_type, CELL_TYPES["Neutrophil"])
|
| 83 |
|
|
|
|
| 84 |
generator = torch.Generator(device="cuda")
|
| 85 |
if int(seed) >= 0:
|
| 86 |
generator.manual_seed(int(seed))
|
| 87 |
|
|
|
|
| 88 |
result = pipeline(
|
| 89 |
prompt=prompt,
|
| 90 |
height=512,
|
|
|
|
| 98 |
|
| 99 |
|
| 100 |
# Build interface
|
| 101 |
+
with gr.Blocks(css=custom_css, theme=gr.themes.Soft(primary_hue="red")) as demo:
|
| 102 |
+
gr.Markdown("""
|
| 103 |
+
# PB Cell Generator
|
| 104 |
+
|
| 105 |
+
Generate synthetic peripheral blood cell images using a fine-tuned Stable Diffusion 2.1 model
|
| 106 |
+
trained on the PBC dataset with detailed morphological captions.
|
| 107 |
+
|
| 108 |
+
**Model:** [esab/pbcell-sd21-v2](https://huggingface.co/esab/pbcell-sd21-v2) | **FID Score:** 79.39 | **Powered by ZeroGPU**
|
| 109 |
+
""")
|
| 110 |
|
| 111 |
with gr.Row():
|
| 112 |
+
with gr.Column(scale=1):
|
| 113 |
+
cell_dropdown = gr.Dropdown(
|
| 114 |
+
choices=CELL_TYPE_LIST,
|
| 115 |
+
value="Neutrophil",
|
| 116 |
+
label="Cell Type",
|
| 117 |
+
info="Select the type of blood cell to generate"
|
| 118 |
+
)
|
| 119 |
+
|
| 120 |
+
custom_box = gr.Textbox(
|
| 121 |
+
label="Custom Prompt (optional)",
|
| 122 |
+
placeholder="Leave empty to use the default morphological prompt for the selected cell type...",
|
| 123 |
+
lines=2,
|
| 124 |
+
info="Override the default prompt with your own description"
|
| 125 |
+
)
|
| 126 |
+
|
| 127 |
+
seed_box = gr.Number(
|
| 128 |
+
value=42,
|
| 129 |
+
label="Seed",
|
| 130 |
+
info="Random seed for reproducibility. Use -1 for random generation.",
|
| 131 |
+
precision=0
|
| 132 |
+
)
|
| 133 |
+
|
| 134 |
+
with gr.Accordion("Advanced Settings", open=False):
|
| 135 |
+
cfg_slider = gr.Slider(
|
| 136 |
+
minimum=1,
|
| 137 |
+
maximum=20,
|
| 138 |
+
value=8.5,
|
| 139 |
+
step=0.5,
|
| 140 |
+
label="Guidance Scale (CFG)",
|
| 141 |
+
info="Controls how closely the image follows the prompt. Higher values = stronger adherence to prompt but may reduce quality. Recommended: 7-9."
|
| 142 |
+
)
|
| 143 |
+
steps_slider = gr.Slider(
|
| 144 |
+
minimum=10,
|
| 145 |
+
maximum=50,
|
| 146 |
+
value=20,
|
| 147 |
+
step=5,
|
| 148 |
+
label="Inference Steps",
|
| 149 |
+
info="Number of denoising steps. More steps = higher quality but slower generation. Recommended: 20-30."
|
| 150 |
+
)
|
| 151 |
+
|
| 152 |
+
btn = gr.Button("Generate Cell Image", variant="primary", elem_classes=["primary-btn"])
|
| 153 |
+
|
| 154 |
+
with gr.Column(scale=1):
|
| 155 |
+
output_img = gr.Image(label="Generated Cell", show_label=True)
|
| 156 |
+
|
| 157 |
+
gr.Markdown("""
|
| 158 |
+
---
|
| 159 |
+
### Supported Cell Types
|
| 160 |
+
|
| 161 |
+
| Cell Type | Description |
|
| 162 |
+
|-----------|-------------|
|
| 163 |
+
| **Neutrophil** | Segmented nucleus, azurophilic granules |
|
| 164 |
+
| **Lymphocyte** | Small cell, high N/C ratio, round nucleus |
|
| 165 |
+
| **Monocyte** | Large cell, kidney-shaped nucleus, vacuoles |
|
| 166 |
+
| **Eosinophil** | Bilobed nucleus, eosinophilic granules |
|
| 167 |
+
| **Basophil** | Segmented nucleus, basophilic granules |
|
| 168 |
+
| **Platelet** | Small anucleate cell fragments |
|
| 169 |
+
| **Erythroblast** | Nucleated red blood cell precursor |
|
| 170 |
+
| **Immature Granulocyte** | Large cell, fine chromatin, nucleoli present |
|
| 171 |
+
|
| 172 |
+
*Note: Erythroblast images may occasionally show multiple cells due to training data characteristics.*
|
| 173 |
+
""")
|
| 174 |
+
|
| 175 |
+
btn.click(
|
| 176 |
+
fn=generate,
|
| 177 |
+
inputs=[cell_dropdown, custom_box, cfg_slider, steps_slider, seed_box],
|
| 178 |
+
outputs=output_img
|
| 179 |
+
)
|
| 180 |
|
| 181 |
demo.launch()
|