[diffusion] fix: fix suppressing error log on non-main ranks (#17712)
This commit is contained in:
@@ -111,6 +111,41 @@ class GPUWorker:
|
|||||||
f"Worker {self.rank}: Initialized device, model, and distributed environment."
|
f"Worker {self.rank}: Initialized device, model, and distributed environment."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def do_mem_analysis(self, output_batch: OutputBatch):
|
||||||
|
peak_memory_bytes = torch.cuda.max_memory_allocated()
|
||||||
|
output_batch.peak_memory_mb = peak_memory_bytes / (1024**2)
|
||||||
|
peak_memory_gb = peak_memory_bytes / (1024**3)
|
||||||
|
remaining_gpu_mem_gb = (
|
||||||
|
current_platform.get_device_total_memory() / (1024**3) - peak_memory_gb
|
||||||
|
)
|
||||||
|
can_stay_resident = self.get_can_stay_resident_components(remaining_gpu_mem_gb)
|
||||||
|
suggested_args = set()
|
||||||
|
component_to_arg = {
|
||||||
|
"vae": "--vae-cpu-offload",
|
||||||
|
"text_encoder": "--text-encoder-cpu-offload",
|
||||||
|
"text_encoder_2": "--text-encoder-cpu-offload",
|
||||||
|
"image_encoder": "--image-encoder-cpu-offload",
|
||||||
|
}
|
||||||
|
|
||||||
|
for component in can_stay_resident:
|
||||||
|
if component == "transformer":
|
||||||
|
if self.server_args.dit_layerwise_offload:
|
||||||
|
suggested_args.add("--dit-layerwise-offload")
|
||||||
|
elif self.server_args.dit_cpu_offload:
|
||||||
|
suggested_args.add("--dit-cpu-offload")
|
||||||
|
elif component in component_to_arg:
|
||||||
|
suggested_args.add(component_to_arg[component])
|
||||||
|
|
||||||
|
suggested_args_str = (
|
||||||
|
", ".join(sorted(suggested_args)) if suggested_args else "None"
|
||||||
|
)
|
||||||
|
logger.info(
|
||||||
|
f"Peak GPU memory: {peak_memory_gb:.2f} GB, "
|
||||||
|
f"Remaining GPU memory at peak: {remaining_gpu_mem_gb:.2f} GB. "
|
||||||
|
f"Components that could stay resident (based on the last request workload): {can_stay_resident}. "
|
||||||
|
f"Related offload server args to disable: {suggested_args_str}"
|
||||||
|
)
|
||||||
|
|
||||||
def execute_forward(self, batch: List[Req]) -> OutputBatch:
|
def execute_forward(self, batch: List[Req]) -> OutputBatch:
|
||||||
"""
|
"""
|
||||||
Execute a forward pass.
|
Execute a forward pass.
|
||||||
@@ -138,23 +173,8 @@ class GPUWorker:
|
|||||||
else:
|
else:
|
||||||
output_batch = result
|
output_batch = result
|
||||||
|
|
||||||
if self.rank == 0:
|
if self.rank == 0 and not req.suppress_logs:
|
||||||
peak_memory_bytes = torch.cuda.max_memory_allocated()
|
self.do_mem_analysis(output_batch)
|
||||||
output_batch.peak_memory_mb = peak_memory_bytes / (1024**2)
|
|
||||||
peak_memory_gb = peak_memory_bytes / (1024**3)
|
|
||||||
remaining_gpu_mem_gb = (
|
|
||||||
current_platform.get_device_total_memory() / (1024**3)
|
|
||||||
- peak_memory_gb
|
|
||||||
)
|
|
||||||
can_stay_resident = self.get_can_stay_resident_components(
|
|
||||||
remaining_gpu_mem_gb
|
|
||||||
)
|
|
||||||
if not req.suppress_logs:
|
|
||||||
logger.info(
|
|
||||||
f"Peak GPU memory: {peak_memory_gb:.2f} GB, "
|
|
||||||
f"Remaining GPU memory at peak: {remaining_gpu_mem_gb:.2f} GB. "
|
|
||||||
f"Components that can stay resident: {can_stay_resident}"
|
|
||||||
)
|
|
||||||
|
|
||||||
duration_ms = (time.monotonic() - start_time) * 1000
|
duration_ms = (time.monotonic() - start_time) * 1000
|
||||||
output_batch.timings.total_duration_ms = duration_ms
|
output_batch.timings.total_duration_ms = duration_ms
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ class InputValidationStage(PipelineStage):
|
|||||||
|
|
||||||
scale = max(ow / iw, oh / ih)
|
scale = max(ow / iw, oh / ih)
|
||||||
img = img.resize((round(iw * scale), round(ih * scale)), Image.LANCZOS)
|
img = img.resize((round(iw * scale), round(ih * scale)), Image.LANCZOS)
|
||||||
logger.info("resized img height: %s, img width: %s", img.height, img.width)
|
logger.debug("resized img height: %s, img width: %s", img.height, img.width)
|
||||||
|
|
||||||
# center-crop
|
# center-crop
|
||||||
x1 = (img.width - ow) // 2
|
x1 = (img.width - ow) // 2
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import os
|
|||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
from contextlib import contextmanager
|
|
||||||
from dataclasses import field
|
from dataclasses import field
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
@@ -1090,8 +1089,6 @@ class PortArgs:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# TODO: not sure what _current_server_args is for, using a _global_server_args instead
|
|
||||||
_current_server_args = None
|
|
||||||
_global_server_args = None
|
_global_server_args = None
|
||||||
|
|
||||||
|
|
||||||
@@ -1103,29 +1100,9 @@ def prepare_server_args(argv: list[str]) -> ServerArgs:
|
|||||||
ServerArgs.add_cli_args(parser)
|
ServerArgs.add_cli_args(parser)
|
||||||
raw_args = parser.parse_args(argv)
|
raw_args = parser.parse_args(argv)
|
||||||
server_args = ServerArgs.from_cli_args(raw_args)
|
server_args = ServerArgs.from_cli_args(raw_args)
|
||||||
global _current_server_args
|
|
||||||
_current_server_args = server_args
|
|
||||||
return server_args
|
return server_args
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def set_current_server_args(server_args: ServerArgs):
|
|
||||||
"""
|
|
||||||
Temporarily set the current sgl_diffusion config.
|
|
||||||
Used during model initialization.
|
|
||||||
We save the current sgl_diffusion config in a global variable,
|
|
||||||
so that all modules can access it, e.g. custom ops
|
|
||||||
can access the sgl_diffusion config to determine how to dispatch.
|
|
||||||
"""
|
|
||||||
global _current_server_args
|
|
||||||
old_server_args = _current_server_args
|
|
||||||
try:
|
|
||||||
_current_server_args = server_args
|
|
||||||
yield
|
|
||||||
finally:
|
|
||||||
_current_server_args = old_server_args
|
|
||||||
|
|
||||||
|
|
||||||
def set_global_server_args(server_args: ServerArgs):
|
def set_global_server_args(server_args: ServerArgs):
|
||||||
"""
|
"""
|
||||||
Set the global sgl_diffusion config for each process
|
Set the global sgl_diffusion config for each process
|
||||||
@@ -1134,17 +1111,7 @@ def set_global_server_args(server_args: ServerArgs):
|
|||||||
_global_server_args = server_args
|
_global_server_args = server_args
|
||||||
|
|
||||||
|
|
||||||
def get_current_server_args() -> ServerArgs | None:
|
def get_global_server_args() -> ServerArgs:
|
||||||
if _current_server_args is None:
|
|
||||||
# in ci, usually when we test custom ops/modules directly,
|
|
||||||
# we don't set the sgl_diffusion config. In that case, we set a default
|
|
||||||
# config.
|
|
||||||
# TODO(will): may need to handle this for CI.
|
|
||||||
raise ValueError("Current sgl_diffusion args is not set.")
|
|
||||||
return _current_server_args
|
|
||||||
|
|
||||||
|
|
||||||
def get_global_server_args() -> ServerArgs | None:
|
|
||||||
if _global_server_args is None:
|
if _global_server_args is None:
|
||||||
# in ci, usually when we test custom ops/modules directly,
|
# in ci, usually when we test custom ops/modules directly,
|
||||||
# we don't set the sgl_diffusion config. In that case, we set a default
|
# we don't set the sgl_diffusion config. In that case, we set a default
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ def get_is_local_main_process():
|
|||||||
|
|
||||||
|
|
||||||
def _log_process_aware(
|
def _log_process_aware(
|
||||||
|
server_log_level: int,
|
||||||
level: int,
|
level: int,
|
||||||
logger_self: Logger,
|
logger_self: Logger,
|
||||||
msg: object,
|
msg: object,
|
||||||
@@ -153,12 +154,12 @@ def _log_process_aware(
|
|||||||
"""Helper function to log a message if the process rank matches the criteria."""
|
"""Helper function to log a message if the process rank matches the criteria."""
|
||||||
is_main_process = get_is_main_process()
|
is_main_process = get_is_main_process()
|
||||||
is_local_main_process = get_is_local_main_process()
|
is_local_main_process = get_is_local_main_process()
|
||||||
|
|
||||||
should_log = (
|
should_log = (
|
||||||
not main_process_only
|
not main_process_only
|
||||||
and not local_main_process_only
|
and not local_main_process_only
|
||||||
or (main_process_only and is_main_process)
|
or (main_process_only and is_main_process)
|
||||||
or (local_main_process_only and is_local_main_process)
|
or (local_main_process_only and is_local_main_process)
|
||||||
|
or server_log_level <= logging.DEBUG
|
||||||
)
|
)
|
||||||
|
|
||||||
if should_log:
|
if should_log:
|
||||||
@@ -234,6 +235,8 @@ def init_logger(name: str) -> _SGLDiffusionLogger:
|
|||||||
|
|
||||||
logger = logging.getLogger(name)
|
logger = logging.getLogger(name)
|
||||||
|
|
||||||
|
server_log_level = logger.getEffectiveLevel()
|
||||||
|
|
||||||
# Patch instance methods
|
# Patch instance methods
|
||||||
setattr(logger, "info_once", MethodType(_print_info_once, logger))
|
setattr(logger, "info_once", MethodType(_print_info_once, logger))
|
||||||
setattr(logger, "warning_once", MethodType(_print_warning_once, logger))
|
setattr(logger, "warning_once", MethodType(_print_warning_once, logger))
|
||||||
@@ -252,6 +255,7 @@ def init_logger(name: str) -> _SGLDiffusionLogger:
|
|||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
_log_process_aware(
|
_log_process_aware(
|
||||||
|
server_log_level,
|
||||||
level,
|
level,
|
||||||
self,
|
self,
|
||||||
msg,
|
msg,
|
||||||
@@ -281,7 +285,7 @@ def init_logger(name: str) -> _SGLDiffusionLogger:
|
|||||||
setattr(
|
setattr(
|
||||||
logger,
|
logger,
|
||||||
"error",
|
"error",
|
||||||
MethodType(_create_patched_method(logging.ERROR, False, True), logger),
|
MethodType(_create_patched_method(logging.ERROR, False, False), logger),
|
||||||
)
|
)
|
||||||
|
|
||||||
return cast(_SGLDiffusionLogger, logger)
|
return cast(_SGLDiffusionLogger, logger)
|
||||||
|
|||||||
Reference in New Issue
Block a user