mirror of
https://github.com/vladmandic/automatic
synced 2026-09-20 01:31:13 +02:00
perf(lora): oversample the hosted-factor sketch to near-exact svd
Sketch hosted deltas at rank+64 with eight power iterations and keep the top rank columns; this lands within noise of the exact decomposition at roughly twice a sketch cost the factor cache pays once per configuration. Bump the cache format so narrower-sketch entries reload as misses.
This commit is contained in:
@@ -96,7 +96,7 @@ def begin_pass(wanted_names):
|
||||
from safetensors import safe_open
|
||||
with safe_open(path, framework='pt', device='cpu') as f:
|
||||
meta = f.metadata() or {}
|
||||
if meta.get('sig') == sig and meta.get('fmt') == '2':
|
||||
if meta.get('sig') == sig and meta.get('fmt') == '3':
|
||||
for k in f.keys():
|
||||
entries[k] = f.get_tensor(k)
|
||||
os.utime(path, None) # freshness for LRU eviction
|
||||
@@ -190,7 +190,7 @@ def flush():
|
||||
from safetensors.torch import save_file
|
||||
os.makedirs(cache_root, exist_ok=True)
|
||||
tmp = state['path'] + '.tmp'
|
||||
save_file(state['store'], tmp, metadata={'sig': state['sig'], 'fmt': '2'})
|
||||
save_file(state['store'], tmp, metadata={'sig': state['sig'], 'fmt': '3'})
|
||||
os.replace(tmp, state['path'])
|
||||
evict()
|
||||
except Exception as e:
|
||||
|
||||
@@ -274,7 +274,9 @@ def apply_hosted(self, network_layer_name, updown, wanted_names, use_previous=Fa
|
||||
# svd_lowrank draws random projections; fork so user generation seeds are untouched and re-applies are deterministic
|
||||
with torch.random.fork_rng(devices=[D.device] if D.device.type == 'cuda' else []):
|
||||
torch.manual_seed(0)
|
||||
U, S, V = torch.svd_lowrank(D, q=q, niter=4)
|
||||
# oversampled sketch with extra power iterations lands within noise of exact svd; only the top q columns are kept
|
||||
U, S, V = torch.svd_lowrank(D, q=min(q + 64, *D.shape), niter=8)
|
||||
U, S, V = U[:, :q], S[:q], V[:, :q]
|
||||
energy = float(S.square().sum() / D.square().sum().clamp(min=1e-30)) # captured fraction, in the weighted domain when calibrated
|
||||
up_h = (U * S).to(dtype=dtype)
|
||||
down_h = V.t()
|
||||
|
||||
Reference in New Issue
Block a user