142 words
1 minute
海象运算符&einops
class Einsum(nn.Module): """Einsum with LoRA support. Can be used as a drop-in replacement for the Gemma Einsum."""
# Shape of the weight. shape: tuple[int, ...] # Initialization function for the weight. init_fn: nn.initializers.Initializer = nn.initializers.zeros # If not None, apply LoRA to the weight. lora_config: LoRAConfig | None = None
def setup(self): self.w = self.param("w", self.init_fn, self.shape)
if config := self.lora_config: # Setup LoRA parameters. shape_a, shape_b = list(self.shape), list(self.shape) shape_a[config.axes[1]] = config.rank shape_b[config.axes[0]] = config.rank self.w_a = self.param("lora_a", config.init_fn, shape_a) self.w_b = self.param("lora_b", config.init_fn, shape_b)
@nn.compact def __call__(self, eqn: str, x): dtype = x.dtype # original dtype, could be half-precision result = jnp.einsum(eqn, x, self.w.astype(dtype))
if config := self.lora_config: eqn_a, eqn_b = self._make_lora_eqns(eqn) lora = jnp.einsum(eqn_a, x, self.w_a.astype(dtype)) lora = jnp.einsum(eqn_b, lora, self.w_b.astype(dtype)) result = result + lora * config.scaling_value
return result