-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmethods.py
More file actions
73 lines (62 loc) · 2.3 KB
/
Copy pathmethods.py
File metadata and controls
73 lines (62 loc) · 2.3 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
from __future__ import annotations
import time
from typing import Callable
import torch
from models import FLUX
from wgnc import project_wgnc
Tensor = torch.Tensor
def optimize_gradient_preconditioning(
*,
flux: FLUX,
reward_model: Callable[[Tensor], Tensor],
prompt: str,
seed: int,
num_iters: int,
lr: float,
grad_clip: float,
guidance: float,
project_latent: bool,
) -> dict[str, object]:
"""ICML 2026 gradient preconditioning on the initial FLUX noise."""
condition = flux.prepare_prompt(prompt)
generator = torch.Generator(device=flux.device).manual_seed(seed)
x = torch.randn(condition.latent_shape, device=flux.device, dtype=torch.float32, generator=generator)
if project_latent:
x = project_wgnc(x)
x = torch.nn.Parameter(x)
opt = torch.optim.Adam([x], lr=lr)
best_reward = -float("inf")
best_image: Tensor | None = None
start = time.perf_counter()
for _ in range(num_iters):
signal = flux.reward_gradient(x, reward_model, condition=condition, guidance=guidance)
reward = signal.reward.mean()
gradient = signal.gradient.detach().to(torch.float32)
grad_rms = gradient.square().mean().sqrt()
if torch.isfinite(grad_rms) and grad_rms > 0:
gradient = project_wgnc(gradient / grad_rms.clamp_min(1e-12))
gradient = gradient * min(float(grad_rms.item()), grad_clip)
else:
gradient = torch.zeros_like(gradient)
opt.zero_grad(set_to_none=True)
x.grad = -gradient
opt.step()
with torch.no_grad():
if project_latent:
x.copy_(project_wgnc(x.detach()))
if float(reward.item()) > best_reward:
best_reward = float(reward.item())
best_image = signal.image.detach()
with torch.no_grad():
final_image = flux.decode(x.detach())
final_reward = float(reward_model(final_image).mean().item())
if final_reward > best_reward:
best_reward = final_reward
best_image = final_image.detach()
if best_image is None:
raise RuntimeError("gradient preconditioning did not produce a finite-reward image")
return {
"image": best_image,
"target_reward": best_reward,
"seconds": time.perf_counter() - start,
}