Core
- Fix: p.data = d is a no-op on __torch_wrapper_subclass__ (QuantizedTensor).
Replace with SlotEntry + module._parameters[key] reassignment, bypassing
PyTorch's wrapper-subclass .data assignment interception.
- Fix: VAE decoder gray/NaN output caused by QuantizedTensor weight remaining
on CPU during fp8 Linear forward.
- Fix: CUDA OOM on Windows when pin_memory=True — reduce pin pool size to
prefetch_count (default 3) instead of W+prefetch (23); only use pin pool
for prefetch loads (non_blocking=True).
- Fix: black output with pin_memory=True — run H2D copies on the transfer
stream, sync before assign_to, so weights are fully written before forward.
- Fix: BlockSwap shutdown crash ("size 5120 vs 0") — offload_block copies
GPU→home directly from slot entries, not through freed block params.
- Fix: Model switch RAM/VRAM leak — clear_pools() drops all pool tensor
references; shutdown sets _blocks = [] and _home = None.
- Fix: update SlotEntry.empty_like to propagate pin_memory for QuantizedTensor
_qdata and _params.scale (was silently unpinned).
- Remove dead code: pinned_pool.py, block_ortho.py (unreferenced).
- Audit utils/ for dead imports (PinnedBlockPool) and stale comments.
Architecture
- SlotEntry: unified data type for ring-buffer slot pool, abstracts regular
Tensor and QuantizedTensor (fp8). copy_from() copies weight data; assign_to()
rewires module._parameters with a fresh GPU QuantizedTensor.
- Ring buffer (cursor % N) replaces free-list for GPU slot allocation.
- PinStage @dataclass: standalone pinned CPU staging ring, built lazily from
GPU entry metadata (safe device-independent construction).
- _detect_model_config(): merge duplicated ~80-line config detection in
load_bernini_model (was written twice for safetensors vs full-SD paths).
- BlockSwapConfig: unified config path. model.load() accepts BerniniBlockSwap
dataclass; model stores it as self._block_swap_config; pre_forward reads it
directly instead of via transformer_options.
Features
- loading_mode dropdown (Full / Streaming) in BerniniR_BlockSwapArgs node.
- Block swap node exposes pin_memory, loading_mode selections.
Context window
- Fix: compatibility with differential diffusion (color blocks, artifacts) —
correct mask accumulation and crossfade when edit_mask is active.
Two fixes for dual-expert 14B sampling:
1. FreeNoise color shift (bernini_sampling.py)
- Clone noise before FreeNoise shuffling so differential diffusion
uses original i.i.d. noise (model trained on i.i.d.).
- FreeNoise-shuffled noise only for k-diffusion x_T initialization.
2. RAM not released after model unload (model_manager.py)
- BerniniRModelHandle.unload() now calls release_model_ram() before
mm.unload_model_and_clones, replacing all parameters with empty
tensors via module._parameters[key] = empty(0).
- Fixed _make_low_wrapper closure dropping high_model reference via
nonlocal, causing the cleanup loop to call None.unload().
- FreeNoise: applied exactly once on the single-sampler path; now also applied on the dual-expert path (was zero)
- TeaCache: restores eager transformer_forward when the model is torch.compiled, so block-skipping actually engages (previously silent no-op)
- Compile cache: isolated to %TEMP%/bernini_r_inductor_cache (env-overridable), version-gated purge + manual purge via BerniniR_CompileModel.purge_cache / BERNINI_PURGE_COMPILE_CACHE
- Removed web/guidance_ui.js frontend (guidance moved to the BerniniR_GuidanceConfig node); dropped WEB_DIRECTORY export
- Stale-comment cleanup across nodes/ and utils/; refreshed README and added README_DEVELOPER
- Bump version to 1.0.3