Skip to content

Commit 19aa211

Browse files
committed
remove svd exp
Signed-off-by: Hao Wu <skyw@nvidia.com>
1 parent 31e482f commit 19aa211

1 file changed

Lines changed: 13 additions & 9 deletions

File tree

emerging_optimizers/soap/rekls.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ class TpRekls(opt_mixin.WeightDecayMixin, optim.Optimizer):
7676
7777
Reimplemented from scratch (not inheriting from :class:`~emerging_optimizers.soap.soap.SOAP`) so the
7878
tensor-parallel bookkeeping stays isolated. Eigenbases are not stored in optimizer state; they are
79-
recomputed via :func:`~emerging_optimizers.soap.soap_utils.get_eigenbasis_svd` from the kronecker
80-
factors. Each step calls svd twice — once on the pre-update L, R for the
79+
recomputed via :func:`~emerging_optimizers.soap.soap_utils.get_eigenbasis_eigh` from the kronecker
80+
factors. Each step calls eigh twice — once on the pre-update L, R for the
8181
:func:`~emerging_optimizers.soap.soap.update_kronecker_factors_kl_shampoo` correction, and once on
8282
the post-update L, R for the gradient projection.
8383
@@ -231,9 +231,9 @@ def step(self, closure: None = None) -> None:
231231
shampoo_beta = 1 - (1 - shampoo_beta) / (1 - shampoo_beta**curr_iter_1_based)
232232

233233
# KL-Shampoo correction needs the eigenbasis of the *pre-update* L, R; recompute it
234-
# via svd since we do not persist eigenbases across steps.
234+
# via eigh since we do not persist eigenbases across steps.
235235
with utils.fp32_matmul_precision(self.fp32_matmul_prec):
236-
pre_eigenbasis_list = soap_utils.get_eigenbasis_svd(kronecker_factor_list)
236+
pre_eigenbasis_list = soap_utils.get_eigenbasis_eigh(kronecker_factor_list)
237237
soap.update_kronecker_factors_kl_shampoo(
238238
kronecker_factor_list,
239239
full_grad,
@@ -249,11 +249,15 @@ def step(self, closure: None = None) -> None:
249249
state["R"].copy_(kronecker_factor_list[1].chunk(self.tp_size, dim=0)[self.tp_rank])
250250

251251
with utils.fp32_matmul_precision(self.fp32_matmul_prec):
252-
# Rotate exp_avg from the pre-update eigenbasis to the post-update eigenbasis
253-
# (matches update_eigenbasis_and_exp_avgs in soap.py for the eigh path; we use svd here).
254-
state["exp_avg"] = soap.precondition(state["exp_avg"], pre_eigenbasis_list, dims=[[0], [1]])
255-
eigenbasis_list = soap_utils.get_eigenbasis_svd(kronecker_factor_list)
256-
state["exp_avg"] = soap.precondition(state["exp_avg"], eigenbasis_list, dims=[[0], [0]])
252+
# Rotate exp_avg from the pre-update eigenbasis to the post-update eigenbasis,
253+
# and recompute the post-update eigenbasis via eigh.
254+
eigenbasis_list, state["exp_avg"], state["exp_avg_sq"] = soap.update_eigenbasis_and_exp_avgs(
255+
kronecker_factor_list=kronecker_factor_list,
256+
eigenbasis_list=pre_eigenbasis_list,
257+
exp_avg_sq=state["exp_avg_sq"],
258+
exp_avg=state["exp_avg"],
259+
use_eigh=True,
260+
)
257261

258262
full_grad_projected = soap.precondition(full_grad, eigenbasis_list, dims=[[0], [0]])
259263

0 commit comments

Comments
 (0)