Add SafeTensors consolidation stage for zero-copy tensor loading
Bundle all per-image modalities (depth, edge, chm, segm) into a single .safetensors file for fast training DataLoader reads (~0.1ms zero-copy mmap vs ~5ms for 4x PNG). Adds consolidate stage after main pipeline stages, save_safetensors/cleanup_npy config flags, resume support, and 10 new tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
41
src/main.py
41
src/main.py
@@ -40,7 +40,8 @@ from src.augmentor.inference import (
|
||||
)
|
||||
from src.augmentor.io_utils import (
|
||||
save_depth_async, save_chmv2_async, save_edges_async,
|
||||
save_segmentation_async, setup_logging, shutdown_io_pool,
|
||||
save_segmentation_async, consolidate_safetensors,
|
||||
setup_logging, shutdown_io_pool,
|
||||
)
|
||||
from src.augmentor.models import (
|
||||
load_depth_model, load_chmv2_model, load_segmentation_model, unload_model,
|
||||
@@ -57,6 +58,7 @@ _STAGE_EMOJI = {
|
||||
"segmentation": "🗺️",
|
||||
"chmv2": "🦕",
|
||||
"concat": "🧩",
|
||||
"consolidate": "📦",
|
||||
}
|
||||
|
||||
|
||||
@@ -313,6 +315,24 @@ def run_segmentation_stage(
|
||||
unload_model(model)
|
||||
|
||||
|
||||
def run_consolidate_stage(
|
||||
records: list[ImageRecord],
|
||||
cleanup_npy: bool = False,
|
||||
) -> None:
|
||||
"""📦 Bundle per-image .npy/.png modalities into .safetensors files."""
|
||||
total = len(records)
|
||||
written = 0
|
||||
pbar = tqdm(records, desc="📦 consolidate → safetensors", unit="img",
|
||||
colour="magenta",
|
||||
bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}]")
|
||||
for r in pbar:
|
||||
ok = consolidate_safetensors(r.output_dir, r.stem, cleanup_npy=cleanup_npy)
|
||||
if ok:
|
||||
written += 1
|
||||
pbar.set_postfix(written=f"{written}/{total}")
|
||||
logger.info("📦 Consolidated %d / %d images to .safetensors.", written, total)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pipeline orchestration
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -408,9 +428,25 @@ def run_pipeline(
|
||||
log_vram_snapshot(f"after {stage}")
|
||||
log_ram_snapshot(f"after {stage}")
|
||||
|
||||
# SafeTensors consolidation: bundle all modalities per image.
|
||||
if pipeline_conf.save_safetensors:
|
||||
pending_st, skipped_st = filter_completed(all_records, "consolidate")
|
||||
logger.info("📦 [consolidate] %d pending, %d skipped.", len(pending_st), skipped_st)
|
||||
if pending_st:
|
||||
t0 = time.perf_counter()
|
||||
run_consolidate_stage(pending_st, cleanup_npy=pipeline_conf.cleanup_npy)
|
||||
elapsed_st = time.perf_counter() - t0
|
||||
stage_times["consolidate"] = elapsed_st
|
||||
stage_counts["consolidate"] = len(pending_st)
|
||||
logger.info("✅ [consolidate] Completed in %.1f s (%d images).",
|
||||
elapsed_st, len(pending_st))
|
||||
else:
|
||||
stage_times["consolidate"] = 0.0
|
||||
stage_counts["consolidate"] = 0
|
||||
|
||||
# Manifest.
|
||||
manifest = {
|
||||
"pipeline_version": "3.2.0-dual-resolution",
|
||||
"pipeline_version": "3.3.0-safetensors",
|
||||
"image_size_db": input_conf.image_size,
|
||||
"image_size_query": input_conf.query_image_size,
|
||||
"profile": hw_conf.profile_name,
|
||||
@@ -420,6 +456,7 @@ def run_pipeline(
|
||||
"segmentation": models_conf.seg_model_type,
|
||||
"chmv2": models_conf.chmv2_model_id,
|
||||
},
|
||||
"save_safetensors": pipeline_conf.save_safetensors,
|
||||
"seg_prompts": seg_conf.prompts,
|
||||
"total_images": len(all_records),
|
||||
"stages": {
|
||||
|
||||
Reference in New Issue
Block a user