Repository navigation
Expand file tree
/
Copy pathinference_runtime.py
More file actions
84 lines (67 loc) · 2.91 KB
/
Copy pathinference_runtime.py
File metadata and controls
84 lines (67 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
"""Application device placement, optional compilation, and progress reporting."""
from __future__ import annotations
from pathlib import Path
import diffusers
import torch
from huggingface_hub.utils import validate_repo_id
DEFAULT_MODEL = "OpenMOSS-Team/MOSS-Image-Base"
def model_source(model):
"""Resolve local bundles without turning Hub IDs into filesystem paths."""
model = str(model).strip()
path = Path(model).expanduser()
if path.is_dir():
if not (path / "pipeline_moss_image.py").is_file():
raise ValueError("The local bundle must include pipeline_moss_image.py from the HF repository.")
return str(path.resolve())
if model.startswith(("/", ".", "~")):
raise FileNotFoundError(f"Model directory does not exist: {model}")
validate_repo_id(model)
return model
def load_pipeline(model, local_files_only=False):
return diffusers.DiffusionPipeline.from_pretrained(
model_source(model),
custom_pipeline="pipeline_moss_image",
trust_remote_code=True,
local_files_only=local_files_only,
torch_dtype={"default": torch.bfloat16, "vae": torch.float32},
)
def set_scheduler(pipe, shift):
pipe.scheduler = type(pipe.scheduler).from_config(pipe.scheduler.config, shift=shift)
def cuda_budget_gib():
if not torch.cuda.is_available():
return 0.0
total = torch.cuda.get_device_properties(0).total_memory
return total * torch.cuda.get_per_process_memory_fraction(0) / 1024**3
def configure_pipeline(pipe, offload="auto", compile_transformer=False):
device = "cuda" if torch.cuda.is_available() else "cpu"
if offload == "auto":
offload = "none" if device == "cpu" or cuda_budget_gib() >= 40 else "model"
if compile_transformer and offload == "sequential":
raise ValueError("Compilation is incompatible with sequential offload.")
if offload == "model":
pipe.enable_model_cpu_offload(device=device)
elif offload == "sequential":
pipe.enable_sequential_cpu_offload(device=device)
elif offload == "none":
pipe.to(device)
else:
raise ValueError(f"Unknown offload mode: {offload}")
if compile_transformer:
for block in (*pipe.transformer.layers, *pipe.transformer.text_embedder.blocks):
block.compile(backend="inductor", fullgraph=True, dynamic=True, mode="default")
return pipe
def generate_with_progress(pipe, report_stage, report_step, **kwargs):
progress_bar = pipe.progress_bar
def progress(items):
report_stage("denoise")
for index, timestep in enumerate(progress_bar(items)):
yield timestep
report_step(pipe, index, timestep, {})
if kwargs.get("output_type", "pil") != "latent":
report_stage("decode")
pipe.progress_bar = progress
try:
report_stage("encode")
return pipe(**kwargs)
finally:
pipe.progress_bar = progress_bar