From 52908bac916b0b1365d979caa0ed7280d07ca0d3 Mon Sep 17 00:00:00 2001 From: Maxim Melichov <80150303+maxmelichov@users.noreply.github.com> Date: Thu, 21 Aug 2025 12:29:40 +0300 Subject: [PATCH 01/10] Update mixer_seq_simple.py --- mamba_ssm/models/mixer_seq_simple.py | 149 ++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 4 deletions(-) diff --git a/mamba_ssm/models/mixer_seq_simple.py b/mamba_ssm/models/mixer_seq_simple.py index fae2257a9..0db8846fe 100644 --- a/mamba_ssm/models/mixer_seq_simple.py +++ b/mamba_ssm/models/mixer_seq_simple.py @@ -16,7 +16,7 @@ from mamba_ssm.modules.mamba2 import Mamba2 from mamba_ssm.modules.mha import MHA from mamba_ssm.modules.mlp import GatedMLP -from mamba_ssm.modules.block import Block +from mamba_ssm.modules.block import Block, DiffBlock, DiffBlockPaper from mamba_ssm.utils.generation import GenerationMixin from mamba_ssm.utils.hf import load_config_hf, load_state_dict_hf @@ -25,8 +25,104 @@ except ImportError: RMSNorm, layer_norm_fn, rms_norm_fn = None, None, None +def create_diff_block( + d_model, + d_intermediate, + ssm_cfg=None, + attn_layer_idx=None, + attn_cfg=None, + norm_epsilon=1e-5, + rms_norm=False, + residual_in_fp32=False, + fused_add_norm=False, + layer_idx=None, + device=None, + dtype=None): + if ssm_cfg is None: + ssm_cfg = {} + if attn_layer_idx is None: + attn_layer_idx = [] + if attn_cfg is None: + attn_cfg = {} + factory_kwargs = {"device": device, "dtype": dtype} + if layer_idx % 4 != 2: # layer_idx % 4 != 1 and layer_idx % 4 != 3: + if layer_idx not in attn_layer_idx: + # Create a copy of the config to modify + ssm_cfg = copy.deepcopy(ssm_cfg) if ssm_cfg is not None else {} + ssm_layer = ssm_cfg.pop("layer", "Mamba1") + if ssm_layer not in ["Mamba1", "Mamba2"]: + raise ValueError(f"Invalid ssm_layer: {ssm_layer}, only support Mamba1 and Mamba2") + mixer_cls = partial( + Mamba2 if ssm_layer == "Mamba2" else Mamba, + layer_idx=layer_idx, + **ssm_cfg, + **factory_kwargs + ) + else: + mixer_cls = partial(MHA, layer_idx=layer_idx, **attn_cfg, **factory_kwargs) + norm_cls = partial( + nn.LayerNorm if not rms_norm else RMSNorm, eps=norm_epsilon, **factory_kwargs + ) + if d_intermediate == 0: + mlp_cls = nn.Identity + else: + mlp_cls = partial( + GatedMLP, hidden_features=d_intermediate, out_features=d_model, **factory_kwargs + ) + block = Block( + d_model, + mixer_cls, + mlp_cls, + norm_cls=norm_cls, + fused_add_norm=fused_add_norm, + residual_in_fp32=residual_in_fp32, + ) + block.layer_idx = layer_idx + else: + if layer_idx not in attn_layer_idx: + # Create a copy of the config to modify + ssm_cfg = copy.deepcopy(ssm_cfg) if ssm_cfg is not None else {} + ssm_layer = ssm_cfg.pop("layer", "Mamba1") + if ssm_layer not in ["Mamba1", "Mamba2"]: + raise ValueError(f"Invalid ssm_layer: {ssm_layer}, only support Mamba1 and Mamba2") + mixer_cls1 = partial( + Mamba2 if ssm_layer == "Mamba2" else Mamba, + layer_idx=layer_idx, + **ssm_cfg, + **factory_kwargs + ) + mixer_cls2 = partial( + Mamba2 if ssm_layer == "Mamba2" else Mamba, + layer_idx=layer_idx, + **ssm_cfg, + **factory_kwargs + ) + else: + mixer_cls1 = partial(MHA, layer_idx=layer_idx, **attn_cfg, **factory_kwargs) + mixer_cls2 = partial(MHA, layer_idx=layer_idx, **attn_cfg, **factory_kwargs) + norm_cls = partial( + nn.LayerNorm if not rms_norm else RMSNorm, eps=norm_epsilon, **factory_kwargs + ) + if d_intermediate == 0: + mlp_cls = nn.Identity + else: + mlp_cls = partial( + GatedMLP, hidden_features=d_intermediate, out_features=d_model, **factory_kwargs + ) + block = DiffBlockPaper( + d_model, + mixer_cls1, + mixer_cls2, + mlp_cls, + norm_cls=norm_cls, + fused_add_norm=fused_add_norm, + residual_in_fp32=residual_in_fp32, + layer_idx=layer_idx, + ) + block.layer_idx = layer_idx + return block -def create_block( +def create_regular_block( d_model, d_intermediate, ssm_cfg=None, @@ -38,8 +134,7 @@ def create_block( fused_add_norm=False, layer_idx=None, device=None, - dtype=None, -): + dtype=None,): if ssm_cfg is None: ssm_cfg = {} if attn_layer_idx is None: @@ -81,6 +176,52 @@ def create_block( block.layer_idx = layer_idx return block +def create_block( + d_model, + d_intermediate, + ssm_cfg=None, + attn_layer_idx=None, + attn_cfg=None, + norm_epsilon=1e-5, + rms_norm=False, + residual_in_fp32=False, + fused_add_norm=False, + layer_idx=None, + device=None, + dtype=None, + mamba_type="DiffMamba", +): + if mamba_type == "DiffMamba": + return create_diff_block( + d_model, + d_intermediate, + ssm_cfg, + attn_layer_idx, + attn_cfg, + norm_epsilon, + rms_norm, + residual_in_fp32, + fused_add_norm, + layer_idx, + device, + dtype + ) + else: + return create_regular_block( + d_model, + d_intermediate, + ssm_cfg, + attn_layer_idx, + attn_cfg, + norm_epsilon, + rms_norm, + residual_in_fp32, + fused_add_norm, + layer_idx, + device, + dtype + ) + # https://github.com/huggingface/transformers/blob/c28d04e9e252a1a099944e325685f14d242ecdcd/src/transformers/models/gpt2/modeling_gpt2.py#L454 def _init_weights( From 4ca04479c658ed94cd37dfd06a0e3225a2640371 Mon Sep 17 00:00:00 2001 From: Maxim Melichov <80150303+maxmelichov@users.noreply.github.com> Date: Thu, 21 Aug 2025 12:30:23 +0300 Subject: [PATCH 02/10] Update block.py --- mamba_ssm/modules/block.py | 235 ++++++++++++++++++++++++++++++++++++- 1 file changed, 234 insertions(+), 1 deletion(-) diff --git a/mamba_ssm/modules/block.py b/mamba_ssm/modules/block.py index 1bd968a0b..607103e9d 100644 --- a/mamba_ssm/modules/block.py +++ b/mamba_ssm/modules/block.py @@ -1,8 +1,11 @@ # Copyright (c) 2024, Tri Dao, Albert Gu. -from typing import Optional +from typing import Optional, Tuple, Type, Callable import torch from torch import nn, Tensor +import torch.nn.functional as F +import os +os.environ["TOKENIZERS_PARALLELISM"] = "false" from mamba_ssm.ops.triton.layer_norm import RMSNorm, layer_norm_fn @@ -89,3 +92,233 @@ def forward( def allocate_inference_cache(self, batch_size, max_seqlen, dtype=None, **kwargs): return self.mixer.allocate_inference_cache(batch_size, max_seqlen, dtype=dtype, **kwargs) + + +class DiffBlockPaper(nn.Module): + """ + Diff-Mamba block: Add->Norm -> (mixer1 || mixer2) -> Norm each -> subtract with λ -> Linear -> Norm + -> (optional MLP sublayer like vanilla Block) + + Returns (hidden_states, residual) with the SAME contract as mamba_ssm.modules.block.Block: + - If no MLP: residual is the pre-norm Add sum, hidden_states is the sublayer output (no add here). + - If MLP: we do residual += hidden_states before norm2+MLP, as in vanilla. + """ + + def __init__( + self, + dim: int, + mixer_cls1: Callable[[int], nn.Module], + mixer_cls2: Callable[[int], nn.Module], + mlp_cls: Callable[[int], nn.Module], + *, + norm_cls: Callable[[int], nn.Module] = nn.LayerNorm, + fused_add_norm: bool = False, + residual_in_fp32: bool = False, + layer_idx: int = 0, + use_postscale: bool = False, # optional extra scaling by (1 - lambda_init) + device: Optional[torch.device] = None, + dtype: Optional[torch.dtype] = None, + ) -> None: + super().__init__() + self.d_model = dim + self.layer_idx = layer_idx + self.fused_add_norm = fused_add_norm + self.residual_in_fp32 = residual_in_fp32 + self.use_postscale = bool(use_postscale) + + # Prenorm for Add->Norm input + self.norm = norm_cls(dim) + + # Two parallel mixers + self.mixer1 = mixer_cls1(dim) + self.mixer2 = mixer_cls2(dim) + + # Post-mixer norms (separate for each branch) and post-sub norm + self.subln = norm_cls(dim) + + # Per-layer scalar λ (σ(λ̄)+λ_init), λ̄ initialized very negative -> small λ + self.lambda_init = 0.8 - 0.6 * torch.exp(torch.tensor(-0.3 * self.layer_idx)) + self.lambda_q1 = nn.Parameter(torch.randn(self.d_model)) + + # Optional second sublayer (MLP) mirrors vanilla Block + if mlp_cls is nn.Identity: + self.mlp = None + else: + self.norm2 = norm_cls(dim) + self.mlp = mlp_cls(dim) + + if self.fused_add_norm: + assert layer_norm_fn is not None, "fused_add_norm=True requires Triton layer_norm_fn" + assert isinstance(self.norm, (nn.LayerNorm, RMSNorm)) if RMSNorm is not None else isinstance(self.norm, nn.LayerNorm) + + # -------- cache helper (lets each mixer see its own cache view) -------- + class _SwapCache: + def __init__(self, ip, idx: int, view): + self.ip, self.idx, self.view, self.orig = ip, idx, view, None + def __enter__(self): + if self.ip is not None: + self.orig = self.ip.key_value_memory_dict.get(self.idx, None) + self.ip.key_value_memory_dict[self.idx] = self.view + def __exit__(self, exc_type, exc, tb): + if self.ip is not None: + if self.orig is None: + self.ip.key_value_memory_dict.pop(self.idx, None) + else: + self.ip.key_value_memory_dict[self.idx] = self.orig + + def _run_mixers(self, x: Tensor, inference_params=None, **mixer_kwargs) -> Tuple[Tensor, Tensor]: + if inference_params is None: + y1 = self.mixer1(x, inference_params=None, **mixer_kwargs) + y2 = self.mixer2(x, inference_params=None, **mixer_kwargs) + return y1, y2 + + slot = inference_params.key_value_memory_dict.get(self.layer_idx, None) + if isinstance(slot, tuple) and len(slot) == 2: + c1, c2 = slot + with DiffBlock._SwapCache(inference_params, self.layer_idx, c1): + y1 = self.mixer1(x, inference_params=inference_params, **mixer_kwargs) + with DiffBlock._SwapCache(inference_params, self.layer_idx, c2): + y2 = self.mixer2(x, inference_params=inference_params, **mixer_kwargs) + else: + y1 = self.mixer1(x, inference_params=inference_params, **mixer_kwargs) + y2 = self.mixer2(x, inference_params=inference_params, **mixer_kwargs) + return y1, y2 + + @staticmethod + def _to_norm_dtype(norm: nn.Module, x: Tensor) -> Tensor: + w = getattr(norm, "weight", None) + return x.to(w.dtype) if isinstance(w, torch.Tensor) else x + + def forward( + self, + hidden_states: Tensor, + residual: Optional[Tensor] = None, + inference_params=None, + **mixer_kwargs, + ) -> Tuple[Tensor, Tensor]: + # ---- Add -> Norm (prenorm) ---- + if not self.fused_add_norm: + residual = (hidden_states + residual) if residual is not None else hidden_states + hidden_states = self.norm(residual.to(dtype=self.norm.weight.dtype)) + if self.residual_in_fp32: + residual = residual.to(torch.float32) + else: + hidden_states, residual = layer_norm_fn( + hidden_states, + self.norm.weight, + self.norm.bias, + residual=residual, + prenorm=True, + residual_in_fp32=self.residual_in_fp32, + eps=self.norm.eps, + is_rms_norm=isinstance(self.norm, RMSNorm) + ) + + # ---- Scalar λ per layer ---- + lambda_q1 = torch.sum(self.lambda_q1, dim=-1).float() + lambda_full = torch.sigmoid(lambda_q1) + self.lambda_init + + # ---- Parallel mixers ---- + y1, y2 = self._run_mixers(hidden_states, inference_params, **mixer_kwargs) + + # ---- Differential combine -> out proj -> post-sub norm ---- + attn = y1 - lambda_full * y2 + attn = self.subln(attn) + + # First sublayer output + hidden_states = attn * (1.0 - self.lambda_init) + + + # ---- Optional MLP sublayer (mirrors vanilla Block) ---- + if self.mlp is not None: + if not self.fused_add_norm: + residual = hidden_states + residual + hidden_states = self.norm2(residual.to(dtype=self.norm2.weight.dtype)) + if self.residual_in_fp32: + residual = residual.to(torch.float32) + else: + hidden_states, residual = layer_norm_fn( + hidden_states, + self.norm2.weight, + self.norm2.bias, + residual=residual, + prenorm=True, + residual_in_fp32=self.residual_in_fp32, + eps=self.norm2.eps, + is_rms_norm=isinstance(self.norm2, RMSNorm) + ) + hidden_states = self.mlp(hidden_states) + else: + residual = hidden_states + residual + + return hidden_states, residual + + def allocate_inference_cache(self, batch_size, max_seqlen, dtype=None, **kwargs): + cache1 = getattr(self.mixer1, "allocate_inference_cache", None) + cache2 = getattr(self.mixer2, "allocate_inference_cache", None) + c1 = cache1(batch_size, max_seqlen, dtype=dtype, **kwargs) if callable(cache1) else None + c2 = cache2(batch_size, max_seqlen, dtype=dtype, **kwargs) if callable(cache2) else None + return (c1, c2) + + @classmethod + def from_pretrained_block( + cls, + block: nn.Module, + mixer_cls: Optional[Callable[[int], nn.Module]] = None, + mlp_cls: Optional[Callable[[int], nn.Module]] = None, + norm_cls: Optional[Callable[[int], nn.Module]] = None, + fused_add_norm: Optional[bool] = None, + residual_in_fp32: Optional[bool] = None, + lambda_init: float = 0.1, + use_postscale: bool = False, + device: Optional[torch.device] = None, + dtype: Optional[torch.dtype] = None, + ) -> "DiffBlock": + """Build a DiffBlock from a vanilla Block and copy weights into both mixers.""" + src_mixer = getattr(block, "mixer", None) + src_mlp = getattr(block, "mlp", None) + src_norm = getattr(block, "norm", None) + + mixer_cls = mixer_cls or (src_mixer.__class__) + mlp_cls = mlp_cls or (src_mlp.__class__ if src_mlp is not None else nn.Identity) + norm_cls = norm_cls or (src_norm.__class__ if src_norm is not None else nn.LayerNorm) + + fused_add_norm = fused_add_norm if fused_add_norm is not None else getattr(block, "fused_add_norm", False) + residual_in_fp32 = residual_in_fp32 if residual_in_fp32 is not None else getattr(block, "residual_in_fp32", False) + + newb = cls( + dim=block.d_model, + mixer_cls1=mixer_cls, + mixer_cls2=mixer_cls, + mlp_cls=mlp_cls, + norm_cls=norm_cls, + fused_add_norm=fused_add_norm, + residual_in_fp32=residual_in_fp32, + layer_idx=getattr(block, "layer_idx", 0), + lambda_init=lambda_init, + use_postscale=use_postscale, + device=device, + dtype=dtype, + ) + + # copy prenorm + if src_norm is not None: + newb.norm.load_state_dict(src_norm.state_dict(), strict=False) + # seed post norms with same stats + newb.post_mamba_norm1.load_state_dict(newb.norm.state_dict(), strict=False) + newb.post_mamba_norm2.load_state_dict(newb.norm.state_dict(), strict=False) + newb.post_sub_norm.load_state_dict(newb.norm.state_dict(), strict=False) + + # copy mixer weights into both mixers + if src_mixer is not None: + st = src_mixer.state_dict() + newb.mixer1.load_state_dict(st, strict=False) + newb.mixer2.load_state_dict(st, strict=False) + + # copy mlp & norm2 if present + if src_mlp is not None and newb.mlp is not None: + newb.mlp.load_state_dict(src_mlp.state_dict(), strict=False) + if hasattr(block, "norm2") and hasattr(newb, "norm2"): + newb.norm2.load_state_dict(block.norm2.state_dict(), strict=False) + + return newb From ee3fd0918f7258dbd316c357763e304855bf4c50 Mon Sep 17 00:00:00 2001 From: Maxim Melichov <80150303+maxmelichov@users.noreply.github.com> Date: Thu, 21 Aug 2025 12:31:52 +0300 Subject: [PATCH 03/10] Update README.md --- README.md | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) diff --git a/README.md b/README.md index bf3b76a93..92dbb9cd1 100755 --- a/README.md +++ b/README.md @@ -1,3 +1,204 @@ +# Differential Mamba + +

+ +Nadav Schneider, +Itamar Zimerman, +Eliya Nachmani + + + +This repository contains the official PyTorch implementation of Differential Mamba paper. +We also provide training code, evaluation code, and model checkpoints to reproduce the results in the paper, including all the baselines. + + + +

+
+ +# Setup +## Clone Project +``` +git clone https://github.com/nadavsc/Diff-Mamba.git +cd Diff-Mamba +``` + +## Create Environment +To set up our environment, please run: +``` +conda env create -f environment.yml +conda activate diffmamba +``` +Note: this should include all the necessary packages to run all the training and evaluation scripts. Nonetheless, make sure the additional requirements are satisfied: + + +Mamba Installation: +``` +pip install causal-conv1d==1.5.0 +pip install mamba-ssm==2.2.4 +``` + +## Additional Requirements - Language Modeling + +Install the requirements in: https://github.com/state-spaces/s4 + +In order to train/evaluate the Language Modeling task, first, download the data. This can be done using the following scripts: +``` +python language_modeling/src/data/datasets/get_wt103.py +bash language_modeling/src/data/transformer-xl/enwik8/get_enwik8.sh +bash language_modeling/src/data/transformer-xl/text8/get_text8.sh +``` +Then, move the resulting datasets into language_modeling/data directory. + +## Additional Requirements - Retrieval + +Install the requirements in: https://github.com/booydar/babilong + +To fine-tune on PG19, please make sure to download the dataset according to the instructions at [deepmind/pg19](https://huggingface.co/datasets/deepmind/pg19) or use the Huggingface dataset version. + +## Additional Requirements - Tuned-Lens + +Install the requirements in: https://github.com/AlignmentResearch/tuned-lens + +Make sure to download The-Pile validation set to train the lens. +Locate the .json or .txt file in the directory tuned-lens/data. + + + +# Experiments +## Language Modeling +Run cd language_modeling. +Then, run the following: +``` +python train.py experiment=lm/diffmamba2-text8 trainer.devices=[0] model.dropout=0.5 loader.l_max=512 train.seed=0 trainer.accumulate_grad_batches=1 loader.batch_size=50 model.n_layers=12 model.d_model=1024 trainer.max_epochs=40 trainer.precision=32 +``` + +```trainer.devices```: used to determine the GPUs for training. [0] use cuda:0 while [2] use cuda:2. [0, 2] will use cuda:0 and cuda:2 with DDP training, while 2 will choose the first two gpus available (cuda:0 and cuda:1). + +```loader.l_max```: the max length or context window for the current training + +```model.n_layers```: determine the model size + +```optimizer.lr```: to change the learning rate, otherwise, use the default + +```trainer.max_epochs```: number of epochs + +```loader.batch_size```: represent the batch size + +```model.dropout```: the dropout of the current model + +```trainer.seed```: responsible of the training seed + +```accumulate_grad_batches```: can be used if the memory in the GPU is not sufficient for the required batch size + + +## Retrieval + + +Run cd retrieval. +To evaluate the models, make sure to save the models checkpoints in the Diff-Mamba/outputs directory. + +### Finetune PG19 +To finetune Mamba on PG19 run: +``` +torchrun --nproc_per_node=4 finetune_pg19.py --model_id=AntonV/mamba2-370m-hf --lr=3e-4 --batch_size=6 --grad_accum_steps=12 --max_steps=4000 --weight_decay=0.1 --warmup=400 --save_steps=500 --eval_steps=500 --output_dir=./outputs/mamba2-370m-pg19-finetune +``` +To finetune Diff-Mamba on PG19 run: +``` +torchrun --nproc_per_node=4 finetune_pg19.py --model_id=AntonV/mamba2-370m-hf --diffmamba --lr=3e-4 --batch_size=6 --grad_accum_steps=12 --max_steps=4000 --weight_decay=0.1 --warmup=400 --save_steps=500 --eval_steps=500 --output_dir=./outputs +``` + +### Finetune BABILong +To finetune Mamba on BABILong run: +``` +torchrun --nproc_per_node=1 finetune_needle.py --ckpt_path=./outputs/mamba2-370m-pg19-finetune --lr=3e-4 --batch_size=6 --grad_accum_steps=1 --max_steps=500 --weight_decay=0.1 --warmup=50 --save_steps=100 --eval_steps=100 --seed=0 --output_dir=./outputs/mamba2-370m-needle-finetune +``` +To finetune Diff-Mamba on BABILong run: +``` +torchrun --nproc_per_node=1 finetune_needle.py --ckpt_path=./outputs/diffmamba2-370m-pg19-finetune --diffmamba --lr=3e-4 --batch_size=6 --grad_accum_steps=1 --max_steps=500 --weight_decay=0.1 --warmup=50 --save_steps=100 --eval_steps=100 --seed=0 --output_dir=./outputs/diffmamba2-370m-needle-finetune +``` + +```--nproc_per_node```: choose number of GPUs for DDP training + +```--grad_accum_steps```: this variable is used to increase effective batch size under memory limitations + +```--diffmamba```: this is a flag that has to be chosen when training Diff-Mamba + +```--model_id```: this is the mamba pretrained model loaded from Huggingface + +### Evaluate + +To evaluate a model on the different tasks and context lengths run: + +``` +bash scripts/run_activation-beacon-diffmamba2-370m-needle-finetune-seed0_no_instruct.sh +``` +or +``` +bash scripts/run_activation-beacon-diffmamba2-370m_pg19-finetune_no_instruct.sh +``` +Results will be saved in the directory scripts/babilong_evals. + +### Plot +To plot the scores, simply run: +``` +python plot.py --model_name diffmamba2-370m-needle-finetune-seed0 --results_folder scripts/babilong_evals/diffmamba2-370m-needle-finetune-seed0 +``` +To plot the relative percentage run: +``` +python plot_compare.py --model_name diffmamba2-370m-needle-finetune --ratio +``` +The plot will be saved in scripts/babilong_evals. Use the flag ```--ratio``` for the relative precentage plot or omit it for the original scores plot + +## Tuned-Lens + + +Run cd tuned-lens. +### Training Lens +Then to train lens for mamba, run: +``` +python -m tuned_lens train --model.name ../../../outputs/mamba2-370m-pg19-finetune --data.name data/valid.txt --per_gpu_batch_size=1 --ssm --output my_lenses/mamba2-370m-pg19-finetune +``` +To train diffmamba, specify the correct path to the model and change the required output directory. +To train the lens in a distributed fashion, change ```--per_gpu_batch_size``` to the number of available GPUs. + +### Evaluate +To evaluate run: +``` +python test_babilong_0k.py --ckpt_path ../../../outputs/mamba2-370m-needle-finetune +``` +add ```--diffmamba``` flag if using Diff-Mamba. + +You can stop the test early when using the flag ```--num_examples```. The compatible lens will be loaded from the my_lenses directory. + +### Plot +To plot the results run: +``` +python plot_tuned_lens.py --diff_results_path results/diffmamba2-370m-needle-finetune-lens_eval.txt --mamba_results_path results/mamba2-370m-needle-finetune-lens_eval.txt +``` +Use ```--log``` to create a log scale plot and ```--start-layer``` and ```--end-layer``` to choose specific layers to plot. + +## Acknowledgements + +All model implementations are based on [Mamba](https://github.com/state-spaces/mamba). Training and evaluation for the language modeling experiments are based on [S4](https://github.com/state-spaces/s4) repository. Evaluation on BABILong is based on [BABILong](https://github.com/booydar/babilong) repo, and measuring signal-to-noise ratio through the layers is based on [tuned-lens](https://github.com/AlignmentResearch/tuned-lens). + +## Citation + +If you use this code, please consider citing the following: + +``` +@misc{schneider2025differentialmamba, + title={Differential Mamba}, + author={Nadav Schneider and Itamar Zimerman and Eliya Nachmani}, + year={2025}, + eprint={2507.06204}, + archivePrefix={arXiv}, + primaryClass={cs.LG}, + url={https://arxiv.org/abs/2507.06204}, +} +``` + + # Mamba ![Mamba](assets/selection.png "Selective State Space") From 421c9dbf1ddf4608417299d15b130a206a867077 Mon Sep 17 00:00:00 2001 From: Maxim Melichov <80150303+maxmelichov@users.noreply.github.com> Date: Sat, 23 Aug 2025 23:15:47 +0300 Subject: [PATCH 04/10] Update block.py --- mamba_ssm/modules/block.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mamba_ssm/modules/block.py b/mamba_ssm/modules/block.py index 607103e9d..54493dbd5 100644 --- a/mamba_ssm/modules/block.py +++ b/mamba_ssm/modules/block.py @@ -175,9 +175,9 @@ def _run_mixers(self, x: Tensor, inference_params=None, **mixer_kwargs) -> Tuple slot = inference_params.key_value_memory_dict.get(self.layer_idx, None) if isinstance(slot, tuple) and len(slot) == 2: c1, c2 = slot - with DiffBlock._SwapCache(inference_params, self.layer_idx, c1): + with DiffBlockPaper._SwapCache(inference_params, self.layer_idx, c1): y1 = self.mixer1(x, inference_params=inference_params, **mixer_kwargs) - with DiffBlock._SwapCache(inference_params, self.layer_idx, c2): + with DiffBlockPaper._SwapCache(inference_params, self.layer_idx, c2): y2 = self.mixer2(x, inference_params=inference_params, **mixer_kwargs) else: y1 = self.mixer1(x, inference_params=inference_params, **mixer_kwargs) @@ -273,7 +273,7 @@ def from_pretrained_block( use_postscale: bool = False, device: Optional[torch.device] = None, dtype: Optional[torch.dtype] = None, - ) -> "DiffBlock": + ) -> "DiffBlockPaper": """Build a DiffBlock from a vanilla Block and copy weights into both mixers.""" src_mixer = getattr(block, "mixer", None) src_mlp = getattr(block, "mlp", None) From 9e29bd6def8567b28a2ef613a63d48274c6d5170 Mon Sep 17 00:00:00 2001 From: Maxim Melichov <80150303+maxmelichov@users.noreply.github.com> Date: Sat, 23 Aug 2025 23:57:07 +0300 Subject: [PATCH 05/10] Remove unused DiffBlock import --- mamba_ssm/models/mixer_seq_simple.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mamba_ssm/models/mixer_seq_simple.py b/mamba_ssm/models/mixer_seq_simple.py index 0db8846fe..2552c9f69 100644 --- a/mamba_ssm/models/mixer_seq_simple.py +++ b/mamba_ssm/models/mixer_seq_simple.py @@ -16,7 +16,7 @@ from mamba_ssm.modules.mamba2 import Mamba2 from mamba_ssm.modules.mha import MHA from mamba_ssm.modules.mlp import GatedMLP -from mamba_ssm.modules.block import Block, DiffBlock, DiffBlockPaper +from mamba_ssm.modules.block import Block, DiffBlockPaper from mamba_ssm.utils.generation import GenerationMixin from mamba_ssm.utils.hf import load_config_hf, load_state_dict_hf From 7d6b9a6d08f290e15c8479d34a7d61cf261a6d1b Mon Sep 17 00:00:00 2001 From: maxmelichov Date: Mon, 25 Aug 2025 10:35:51 +0300 Subject: [PATCH 06/10] Remove MANIFEST.in and usage.md; update license in pyproject.toml and setup.py to BSD; adjust CUDA architecture flags in setup.py; update version to 2.2.4 in __init__.py; modify import paths in various files to reflect new package structure. --- .github/workflows/publish.yaml | 24 ++- MANIFEST.in | 3 - README.md | 201 ---------------------- mamba_ssm/__init__.py | 2 +- mamba_ssm/models/mixer_seq_simple.py | 18 +- mamba_ssm/modules/block.py | 2 +- mamba_ssm/ops/selective_scan_interface.py | 16 +- mamba_ssm/ops/triton/ssd_chunk_scan.py | 15 +- mamba_ssm/ops/triton/ssd_chunk_state.py | 27 +-- mamba_ssm/ops/triton/ssd_combined.py | 39 ++--- pyproject.toml | 3 +- setup.py | 27 ++- usage.md | 43 ----- 13 files changed, 71 insertions(+), 349 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 usage.md diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index a0b09fa78..192f95626 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -40,12 +40,12 @@ jobs: strategy: fail-fast: false matrix: - # Using ubuntu-22.04 instead of 24.04 for more compatibility (glibc). Ideally we'd use the + # Using ubuntu-20.04 instead of 22.04 for more compatibility (glibc). Ideally we'd use the # manylinux docker image, but I haven't figured out how to install CUDA on manylinux. - os: [ubuntu-22.04] + os: [ubuntu-20.04] python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] - torch-version: ['2.4.0', '2.5.1', '2.6.0', '2.7.1'] - cuda-version: ['11.8.0', '12.9.1'] + torch-version: ['2.1.2', '2.2.2', '2.3.1', '2.4.0', '2.5.1', '2.6.0.dev20241001'] + cuda-version: ['11.8.0', '12.3.2'] # We need separate wheels that either uses C++11 ABI (-D_GLIBCXX_USE_CXX11_ABI) or not. # Pytorch wheels currently don't use it, but nvcr images have Pytorch compiled with C++11 ABI. # Without this we get import error (undefined symbol: _ZN3c105ErrorC2ENS_14SourceLocationESs) @@ -53,6 +53,16 @@ jobs: cxx11_abi: ['FALSE', 'TRUE'] exclude: # see https://github.com/pytorch/pytorch/blob/main/RELEASE.md#release-compatibility-matrix + # Pytorch < 2.2 does not support Python 3.12 + - torch-version: '2.1.2' + python-version: '3.12' + # Pytorch < 2.5 does not support Python 3.13 + - torch-version: '2.1.2' + python-version: '3.13' + - torch-version: '2.2.2' + python-version: '3.13' + - torch-version: '2.3.1' + python-version: '3.13' - torch-version: '2.4.0' python-version: '3.13' @@ -89,7 +99,7 @@ jobs: - name: Install CUDA ${{ matrix.cuda-version }} if: ${{ matrix.cuda-version != 'cpu' }} - uses: Jimver/cuda-toolkit@v0.2.26 + uses: Jimver/cuda-toolkit@v0.2.19 id: cuda-toolkit with: cuda: ${{ matrix.cuda-version }} @@ -111,8 +121,8 @@ jobs: # e.g. we can have system CUDA version being 11.7 but if torch==1.12 then we need to download the wheel from cu116 # This code is ugly, maybe there's a better way to do this. export TORCH_CUDA_VERSION=$(python -c "from os import environ as env; \ - minv = {'2.4': 118, '2.5': 118, '2.6': 118, '2.7': 118}[env['MATRIX_TORCH_VERSION']]; \ - maxv = {'2.4': 124, '2.5': 124, '2.6': 126, '2.7': 128}[env['MATRIX_TORCH_VERSION']]; \ + minv = {'2.1': 118, '2.2': 118, '2.3': 118, '2.4': 118, '2.5': 118, '2.6': 118}[env['MATRIX_TORCH_VERSION']]; \ + maxv = {'2.1': 121, '2.2': 121, '2.3': 121, '2.4': 124, '2.5': 124, '2.6': 124}[env['MATRIX_TORCH_VERSION']]; \ print(minv if int(env['MATRIX_CUDA_VERSION']) < 120 else maxv)" \ ) if [[ ${{ matrix.torch-version }} == *"dev"* ]]; then diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 318499d57..000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,3 +0,0 @@ -recursive-include csrc * -recursive-include csrc * -README.md diff --git a/README.md b/README.md index 92dbb9cd1..bf3b76a93 100755 --- a/README.md +++ b/README.md @@ -1,204 +1,3 @@ -# Differential Mamba - -

- -Nadav Schneider, -Itamar Zimerman, -Eliya Nachmani - - - -This repository contains the official PyTorch implementation of Differential Mamba paper. -We also provide training code, evaluation code, and model checkpoints to reproduce the results in the paper, including all the baselines. - - - -

-
- -# Setup -## Clone Project -``` -git clone https://github.com/nadavsc/Diff-Mamba.git -cd Diff-Mamba -``` - -## Create Environment -To set up our environment, please run: -``` -conda env create -f environment.yml -conda activate diffmamba -``` -Note: this should include all the necessary packages to run all the training and evaluation scripts. Nonetheless, make sure the additional requirements are satisfied: - - -Mamba Installation: -``` -pip install causal-conv1d==1.5.0 -pip install mamba-ssm==2.2.4 -``` - -## Additional Requirements - Language Modeling - -Install the requirements in: https://github.com/state-spaces/s4 - -In order to train/evaluate the Language Modeling task, first, download the data. This can be done using the following scripts: -``` -python language_modeling/src/data/datasets/get_wt103.py -bash language_modeling/src/data/transformer-xl/enwik8/get_enwik8.sh -bash language_modeling/src/data/transformer-xl/text8/get_text8.sh -``` -Then, move the resulting datasets into language_modeling/data directory. - -## Additional Requirements - Retrieval - -Install the requirements in: https://github.com/booydar/babilong - -To fine-tune on PG19, please make sure to download the dataset according to the instructions at [deepmind/pg19](https://huggingface.co/datasets/deepmind/pg19) or use the Huggingface dataset version. - -## Additional Requirements - Tuned-Lens - -Install the requirements in: https://github.com/AlignmentResearch/tuned-lens - -Make sure to download The-Pile validation set to train the lens. -Locate the .json or .txt file in the directory tuned-lens/data. - - - -# Experiments -## Language Modeling -Run cd language_modeling. -Then, run the following: -``` -python train.py experiment=lm/diffmamba2-text8 trainer.devices=[0] model.dropout=0.5 loader.l_max=512 train.seed=0 trainer.accumulate_grad_batches=1 loader.batch_size=50 model.n_layers=12 model.d_model=1024 trainer.max_epochs=40 trainer.precision=32 -``` - -```trainer.devices```: used to determine the GPUs for training. [0] use cuda:0 while [2] use cuda:2. [0, 2] will use cuda:0 and cuda:2 with DDP training, while 2 will choose the first two gpus available (cuda:0 and cuda:1). - -```loader.l_max```: the max length or context window for the current training - -```model.n_layers```: determine the model size - -```optimizer.lr```: to change the learning rate, otherwise, use the default - -```trainer.max_epochs```: number of epochs - -```loader.batch_size```: represent the batch size - -```model.dropout```: the dropout of the current model - -```trainer.seed```: responsible of the training seed - -```accumulate_grad_batches```: can be used if the memory in the GPU is not sufficient for the required batch size - - -## Retrieval - - -Run cd retrieval. -To evaluate the models, make sure to save the models checkpoints in the Diff-Mamba/outputs directory. - -### Finetune PG19 -To finetune Mamba on PG19 run: -``` -torchrun --nproc_per_node=4 finetune_pg19.py --model_id=AntonV/mamba2-370m-hf --lr=3e-4 --batch_size=6 --grad_accum_steps=12 --max_steps=4000 --weight_decay=0.1 --warmup=400 --save_steps=500 --eval_steps=500 --output_dir=./outputs/mamba2-370m-pg19-finetune -``` -To finetune Diff-Mamba on PG19 run: -``` -torchrun --nproc_per_node=4 finetune_pg19.py --model_id=AntonV/mamba2-370m-hf --diffmamba --lr=3e-4 --batch_size=6 --grad_accum_steps=12 --max_steps=4000 --weight_decay=0.1 --warmup=400 --save_steps=500 --eval_steps=500 --output_dir=./outputs -``` - -### Finetune BABILong -To finetune Mamba on BABILong run: -``` -torchrun --nproc_per_node=1 finetune_needle.py --ckpt_path=./outputs/mamba2-370m-pg19-finetune --lr=3e-4 --batch_size=6 --grad_accum_steps=1 --max_steps=500 --weight_decay=0.1 --warmup=50 --save_steps=100 --eval_steps=100 --seed=0 --output_dir=./outputs/mamba2-370m-needle-finetune -``` -To finetune Diff-Mamba on BABILong run: -``` -torchrun --nproc_per_node=1 finetune_needle.py --ckpt_path=./outputs/diffmamba2-370m-pg19-finetune --diffmamba --lr=3e-4 --batch_size=6 --grad_accum_steps=1 --max_steps=500 --weight_decay=0.1 --warmup=50 --save_steps=100 --eval_steps=100 --seed=0 --output_dir=./outputs/diffmamba2-370m-needle-finetune -``` - -```--nproc_per_node```: choose number of GPUs for DDP training - -```--grad_accum_steps```: this variable is used to increase effective batch size under memory limitations - -```--diffmamba```: this is a flag that has to be chosen when training Diff-Mamba - -```--model_id```: this is the mamba pretrained model loaded from Huggingface - -### Evaluate - -To evaluate a model on the different tasks and context lengths run: - -``` -bash scripts/run_activation-beacon-diffmamba2-370m-needle-finetune-seed0_no_instruct.sh -``` -or -``` -bash scripts/run_activation-beacon-diffmamba2-370m_pg19-finetune_no_instruct.sh -``` -Results will be saved in the directory scripts/babilong_evals. - -### Plot -To plot the scores, simply run: -``` -python plot.py --model_name diffmamba2-370m-needle-finetune-seed0 --results_folder scripts/babilong_evals/diffmamba2-370m-needle-finetune-seed0 -``` -To plot the relative percentage run: -``` -python plot_compare.py --model_name diffmamba2-370m-needle-finetune --ratio -``` -The plot will be saved in scripts/babilong_evals. Use the flag ```--ratio``` for the relative precentage plot or omit it for the original scores plot - -## Tuned-Lens - - -Run cd tuned-lens. -### Training Lens -Then to train lens for mamba, run: -``` -python -m tuned_lens train --model.name ../../../outputs/mamba2-370m-pg19-finetune --data.name data/valid.txt --per_gpu_batch_size=1 --ssm --output my_lenses/mamba2-370m-pg19-finetune -``` -To train diffmamba, specify the correct path to the model and change the required output directory. -To train the lens in a distributed fashion, change ```--per_gpu_batch_size``` to the number of available GPUs. - -### Evaluate -To evaluate run: -``` -python test_babilong_0k.py --ckpt_path ../../../outputs/mamba2-370m-needle-finetune -``` -add ```--diffmamba``` flag if using Diff-Mamba. - -You can stop the test early when using the flag ```--num_examples```. The compatible lens will be loaded from the my_lenses directory. - -### Plot -To plot the results run: -``` -python plot_tuned_lens.py --diff_results_path results/diffmamba2-370m-needle-finetune-lens_eval.txt --mamba_results_path results/mamba2-370m-needle-finetune-lens_eval.txt -``` -Use ```--log``` to create a log scale plot and ```--start-layer``` and ```--end-layer``` to choose specific layers to plot. - -## Acknowledgements - -All model implementations are based on [Mamba](https://github.com/state-spaces/mamba). Training and evaluation for the language modeling experiments are based on [S4](https://github.com/state-spaces/s4) repository. Evaluation on BABILong is based on [BABILong](https://github.com/booydar/babilong) repo, and measuring signal-to-noise ratio through the layers is based on [tuned-lens](https://github.com/AlignmentResearch/tuned-lens). - -## Citation - -If you use this code, please consider citing the following: - -``` -@misc{schneider2025differentialmamba, - title={Differential Mamba}, - author={Nadav Schneider and Itamar Zimerman and Eliya Nachmani}, - year={2025}, - eprint={2507.06204}, - archivePrefix={arXiv}, - primaryClass={cs.LG}, - url={https://arxiv.org/abs/2507.06204}, -} -``` - - # Mamba ![Mamba](assets/selection.png "Selective State Space") diff --git a/mamba_ssm/__init__.py b/mamba_ssm/__init__.py index 6280931e4..ac4f6e311 100644 --- a/mamba_ssm/__init__.py +++ b/mamba_ssm/__init__.py @@ -1,4 +1,4 @@ -__version__ = "2.2.5" +__version__ = "2.2.4" from mamba_ssm.ops.selective_scan_interface import selective_scan_fn, mamba_inner_fn from mamba_ssm.modules.mamba_simple import Mamba diff --git a/mamba_ssm/models/mixer_seq_simple.py b/mamba_ssm/models/mixer_seq_simple.py index 2552c9f69..7a22a2b71 100644 --- a/mamba_ssm/models/mixer_seq_simple.py +++ b/mamba_ssm/models/mixer_seq_simple.py @@ -11,17 +11,17 @@ import torch import torch.nn as nn -from mamba_ssm.models.config_mamba import MambaConfig -from mamba_ssm.modules.mamba_simple import Mamba -from mamba_ssm.modules.mamba2 import Mamba2 -from mamba_ssm.modules.mha import MHA -from mamba_ssm.modules.mlp import GatedMLP -from mamba_ssm.modules.block import Block, DiffBlockPaper -from mamba_ssm.utils.generation import GenerationMixin -from mamba_ssm.utils.hf import load_config_hf, load_state_dict_hf +from DiffMamba.mamba_ssm.models.config_mamba import MambaConfig +from DiffMamba.mamba_ssm.modules.mamba_simple import Mamba +from DiffMamba.mamba_ssm.modules.mamba2 import Mamba2 +from DiffMamba.mamba_ssm.modules.mha import MHA +from DiffMamba.mamba_ssm.modules.mlp import GatedMLP +from DiffMamba.mamba_ssm.modules.block import Block, DiffBlockPaper +from DiffMamba.mamba_ssm.utils.generation import GenerationMixin +from DiffMamba.mamba_ssm.utils.hf import load_config_hf, load_state_dict_hf try: - from mamba_ssm.ops.triton.layer_norm import RMSNorm, layer_norm_fn, rms_norm_fn + from DiffMamba.mamba_ssm.ops.triton.layer_norm import RMSNorm, layer_norm_fn, rms_norm_fn except ImportError: RMSNorm, layer_norm_fn, rms_norm_fn = None, None, None diff --git a/mamba_ssm/modules/block.py b/mamba_ssm/modules/block.py index 54493dbd5..1a7e06340 100644 --- a/mamba_ssm/modules/block.py +++ b/mamba_ssm/modules/block.py @@ -7,7 +7,7 @@ import os os.environ["TOKENIZERS_PARALLELISM"] = "false" -from mamba_ssm.ops.triton.layer_norm import RMSNorm, layer_norm_fn +from DiffMamba.mamba_ssm.ops.triton.layer_norm import RMSNorm, layer_norm_fn class Block(nn.Module): diff --git a/mamba_ssm/ops/selective_scan_interface.py b/mamba_ssm/ops/selective_scan_interface.py index a41f1359c..c51ec40dc 100644 --- a/mamba_ssm/ops/selective_scan_interface.py +++ b/mamba_ssm/ops/selective_scan_interface.py @@ -8,12 +8,10 @@ try: from causal_conv1d import causal_conv1d_fn - from causal_conv1d.cpp_functions import causal_conv1d_fwd_function, causal_conv1d_bwd_function, causal_conv1d_update_function + import causal_conv1d_cuda except ImportError: causal_conv1d_fn = None - causal_conv1d_fwd_function = None - causal_conv1d_bwd_function = None - causal_conv1d_update_function = None + causal_conv1d_cuda = None from mamba_ssm.ops.triton.layer_norm import _layer_norm_fwd @@ -192,7 +190,7 @@ def forward(ctx, xz, conv1d_weight, conv1d_bias, x_proj_weight, delta_proj_weigh """ xz: (batch, dim, seqlen) """ - assert causal_conv1d_fwd_function is not None, "causal_conv1d_cuda is not available. Please install causal-conv1d." + assert causal_conv1d_cuda is not None, "causal_conv1d_cuda is not available. Please install causal-conv1d." assert checkpoint_lvl in [0, 1] L = xz.shape[-1] delta_rank = delta_proj_weight.shape[1] @@ -208,7 +206,7 @@ def forward(ctx, xz, conv1d_weight, conv1d_bias, x_proj_weight, delta_proj_weigh conv1d_weight = rearrange(conv1d_weight, "d 1 w -> d w") x, z = xz.chunk(2, dim=1) conv1d_bias = conv1d_bias.contiguous() if conv1d_bias is not None else None - conv1d_out = causal_conv1d_fwd_function( + conv1d_out = causal_conv1d_cuda.causal_conv1d_fwd( x, conv1d_weight, conv1d_bias, None, None, None, True ) # We're being very careful here about the layout, to avoid extra transposes. @@ -281,7 +279,7 @@ def forward(ctx, xz, conv1d_weight, conv1d_bias, x_proj_weight, delta_proj_weigh @custom_bwd def backward(ctx, dout): # dout: (batch, seqlen, dim) - assert causal_conv1d_fwd_function is not None, "causal_conv1d_cuda is not available. Please install causal-conv1d." + assert causal_conv1d_cuda is not None, "causal_conv1d_cuda is not available. Please install causal-conv1d." (xz, conv1d_weight, conv1d_bias, x_dbl, x_proj_weight, delta_proj_weight, out_proj_weight, conv1d_out, delta, A, B, C, D, delta_bias, scan_intermediates, b_rms_weight, c_rms_weight, dt_rms_weight, out) = ctx.saved_tensors L = xz.shape[-1] @@ -291,7 +289,7 @@ def backward(ctx, dout): if dout.stride(-1) != 1: dout = dout.contiguous() if ctx.checkpoint_lvl == 1: - conv1d_out = causal_conv1d_fwd_function( + conv1d_out = causal_conv1d_cuda.causal_conv1d_fwd( x, conv1d_weight, conv1d_bias, None, None, None, True ) delta = rearrange(delta_proj_weight @ x_dbl[:, :delta_rank].t(), @@ -357,7 +355,7 @@ def backward(ctx, dout): dconv1d_out = rearrange(dconv1d_out, "d (b l) -> b d l", b=x.shape[0], l=x.shape[-1]) # The kernel supports passing in a pre-allocated dx (e.g., in case we want to fuse the # backward of conv1d with the backward of chunk). - dx, dconv1d_weight, dconv1d_bias, *_ = causal_conv1d_bwd_function( + dx, dconv1d_weight, dconv1d_bias, *_ = causal_conv1d_cuda.causal_conv1d_bwd( x, conv1d_weight, conv1d_bias, dconv1d_out, None, None, None, dx, False, True ) dconv1d_bias = dconv1d_bias if conv1d_bias is not None else None diff --git a/mamba_ssm/ops/triton/ssd_chunk_scan.py b/mamba_ssm/ops/triton/ssd_chunk_scan.py index 959078061..fa5b813a2 100644 --- a/mamba_ssm/ops/triton/ssd_chunk_scan.py +++ b/mamba_ssm/ops/triton/ssd_chunk_scan.py @@ -132,8 +132,7 @@ def _chunk_scan_fwd_kernel( dA_cs_k = tl.load(dA_cumsum_ptrs, mask=offs_k < chunk_size - k, other=0.0).to(tl.float32) # If there's seq_idx, we already set cb[i, j] = 0 for seq_idx[i] != seq_idx[j]. # So we don't need masking wrt seq_idx here. - # cb *= tl.exp((dA_cs_m[:, None] - dA_cs_k[None, :])) - cb *= tl.exp(tl.minimum((dA_cs_m[:, None] - dA_cs_k[None, :]), 0.0)) + cb *= tl.exp((dA_cs_m[:, None] - dA_cs_k[None, :])) dt_k = tl.load(dt_ptrs, mask=offs_k < chunk_size - k, other=0.0).to(tl.float32) cb *= dt_k if IS_CAUSAL: @@ -680,8 +679,7 @@ def _chunk_scan_bwd_dx_kernel( cb = tl.load(cb_ptrs, mask=(offs_m[:, None] < chunk_size) & (offs_k[None, :] < K_MAX - k), other=0.0) dout = tl.load(dout_ptrs, mask=(offs_k[:, None] < K_MAX - k) & (offs_n[None, :] < hdim), other=0.0) dA_cs_k = tl.load(dA_cumsum_ptrs, mask=offs_k < K_MAX - k, other=0.0).to(tl.float32) - # cb *= tl.exp(dA_cs_k[None, :] - dA_cs_m[:, None]) - cb *= tl.exp(tl.minimum((dA_cs_k[None, :] - dA_cs_m[:, None]), 0.0)) + cb *= tl.exp(dA_cs_k[None, :] - dA_cs_m[:, None]) # If we don't have the (k + offs_k[None, :] < K_MAX) mask, for indices outside this range, # we might have dA_cs_m = 0.0 and dA_cs_k very negative, and tl.exp will return inf. # Multiplying with cb, which is 0.0 outside the range, will make the result NaN. @@ -818,8 +816,7 @@ def _chunk_scan_bwd_dcb_kernel( dcb *= dt_n dA_cs_m = tl.load(dA_cumsum_ptr + offs_m * stride_dA_cs_csize, mask=offs_m < chunk_size_limit, other=0.0).to(tl.float32) dA_cs_n = tl.load(dA_cumsum_ptr + offs_n * stride_dA_cs_csize, mask=offs_n < chunk_size_limit, other=0.0).to(tl.float32) - # dcb *= tl.exp(dA_cs_m[:, None] - dA_cs_n[None, :]) - dcb *= tl.exp(tl.minimum((dA_cs_m[:, None] - dA_cs_n[None, :]), 0.0)) + dcb *= tl.exp(dA_cs_m[:, None] - dA_cs_n[None, :]) if HAS_DDA_CS: tl.static_assert(not HAS_SEQ_IDX, "HAS_SEQ_IDX not supported with HAS_DDA_CS yet") ddA_cs = dcb * cb @@ -1011,8 +1008,7 @@ def _chunk_scan_bwd_ddAcs_stable_kernel_old( acc *= dt_n dA_cs_m = tl.load(dA_cumsum_ptr + offs_m * stride_dA_cs_csize, mask=offs_m < chunk_size, other=0.0).to(tl.float32) dA_cs_n = tl.load(dA_cumsum_ptr + offs_n * stride_dA_cs_csize, mask=offs_n < chunk_size, other=0.0).to(tl.float32) - # acc *= tl.exp(dA_cs_m[:, None] - dA_cs_n[None, :]) - acc *= tl.exp(tl.minimum((dA_cs_m[:, None] - dA_cs_n[None, :]), 0.0)) + acc *= tl.exp(dA_cs_m[:, None] - dA_cs_n[None, :]) mask = offs_m[:, None] >= offs_n[None, :] + 1 acc = tl.where(mask, acc, 0.0) acc = tl.cumsum(acc, axis=1) @@ -1138,8 +1134,7 @@ def _chunk_scan_bwd_ddAcs_stable_kernel( cb = tl.load(cb_ptrs, mask=(offs_m[:, None] < chunk_size) & (offs_n[None, :] < chunk_size - start_n), other=0.0).to(tl.float32) acc *= cb dA_cs_n = tl.load(dA_cumsum_ptr + (start_n + offs_n) * stride_dA_cs_csize, mask=offs_n < chunk_size - start_n, other=0.0).to(tl.float32) - # acc *= tl.exp(dA_cs_m[:, None] - dA_cs_n[None, :]) - acc *= tl.exp(tl.minimum((dA_cs_m[:, None] - dA_cs_n[None, :]), 0.0)) + acc *= tl.exp(dA_cs_m[:, None] - dA_cs_n[None, :]) mask = offs_m[:, None] >= start_n + offs_n[None, :] + 1 acc = tl.where(mask, acc, 0.0) rowsum_new = rowsum + tl.sum(acc, axis=1) diff --git a/mamba_ssm/ops/triton/ssd_chunk_state.py b/mamba_ssm/ops/triton/ssd_chunk_state.py index 50838d055..bb49c9a96 100644 --- a/mamba_ssm/ops/triton/ssd_chunk_state.py +++ b/mamba_ssm/ops/triton/ssd_chunk_state.py @@ -141,7 +141,7 @@ def _chunk_cumsum_bwd_kernel( dt += dt_bias[:, None] if DT_SOFTPLUS: dt_presoftplus = dt - dt = tl.where(dt <= 20.0, softplus(dt), dt) + dt = tl.where(dt <= 20.0, softplus(dt), ddt) clamp_mask = (dt < dt_min) | (dt > dt_max) # As of Triton 2.2.0, tl.clamp is not available yet # dt = tl.clamp(dt, dt_min, dt_max) @@ -229,11 +229,9 @@ def _chunk_state_fwd_kernel( seq_idx_k = tl.load(seq_idx_ptrs, mask=offs_k < chunk_size_limit - k, other=-1) dt_k = tl.load(dt_ptrs, mask=offs_k < chunk_size_limit - k, other=0.0).to(tl.float32) if not HAS_SEQ_IDX: - # scale = tl.exp((dA_cs_last - dA_cs_k)) * dt_k - scale = tl.exp(tl.minimum((dA_cs_last - dA_cs_k), 0.0)) * dt_k + scale = tl.exp((dA_cs_last - dA_cs_k)) * dt_k else: - # scale = tl.where(seq_idx_k == seq_idx_last, tl.exp((dA_cs_last - dA_cs_k)) * dt_k, 0.0) - scale = tl.where(seq_idx_k == seq_idx_last, tl.exp(tl.minimum((dA_cs_last - dA_cs_k), 0.0)) * dt_k, 0.0) + scale = tl.where(seq_idx_k == seq_idx_last, tl.exp((dA_cs_last - dA_cs_k)) * dt_k, 0.0) b *= scale[:, None] b = b.to(x_ptr.dtype.element_ty) acc += tl.dot(x, b) @@ -334,8 +332,7 @@ def _chunk_state_bwd_dx_kernel( dA_cumsum_ptrs = dA_cumsum_ptr + offs_m * stride_dA_cs_csize dA_cs_m = tl.load(dA_cumsum_ptrs, mask=offs_m < chunk_size, other=0.0).to(tl.float32) dt_m = tl.load(dt_ptrs, mask=offs_m < chunk_size, other=0.0).to(tl.float32) - # acc *= tl.exp(dA_cs_last - dA_cs_m)[:, None] - acc *= tl.exp(tl.minimum((dA_cs_last - dA_cs_m), 0.0))[:, None] + acc *= tl.exp(dA_cs_last - dA_cs_m)[:, None] x_ptrs = x_ptr + (offs_m[:, None] * stride_x_seqlen + offs_n[None, :] * stride_x_hdim) x = tl.load(x_ptrs, mask=(offs_m[:, None] < chunk_size_limit) & (offs_n[None, :] < hdim), other=0.0).to(tl.float32) @@ -437,11 +434,9 @@ def _chunk_state_bwd_db_kernel( dA_cs_m = tl.load(dA_cumsum_ptrs, mask=offs_m < chunk_size, other=0.0).to(tl.float32) dt_m = tl.load(dt_ptrs, mask=offs_m < chunk_size, other=0.0).to(tl.float32) if not HAS_SEQ_IDX: - # scale = tl.exp(dA_cs_last - dA_cs_m) - scale = tl.exp(tl.minimum((dA_cs_last - dA_cs_m), 0.0)) + scale = tl.exp(dA_cs_last - dA_cs_m) else: - # scale = tl.where(seq_idx_m == seq_idx_last, tl.exp(dA_cs_last - dA_cs_m), 0.0) - scale = tl.where(seq_idx_m == seq_idx_last, tl.exp(tl.minimum((dA_cs_last - dA_cs_m), 0.0)), 0.0) + scale = tl.where(seq_idx_m == seq_idx_last, tl.exp(dA_cs_last - dA_cs_m), 0.0) db *= (scale * dt_m)[:, None] if HAS_DDA_CS: # This is the gradient wrt (dA_cs_last - dA_cs_m), i.e. the exclusive reverse cumsum @@ -554,13 +549,11 @@ def _chunk_state_bwd_ddAcs_stable_kernel( dA_cs_m = tl.load(dA_cumsum_ptr + offs_m * stride_dA_cs_csize, mask=offs_m < chunk_size, other=0.0).to(tl.float32) dA_cs_last = tl.load(dA_cumsum_ptr + (chunk_size - 1) * stride_dA_cs_csize).to(tl.float32) if not HAS_SEQ_IDX: - # scale = tl.exp(dA_cs_last - dA_cs_m) - scale = tl.exp(tl.minimum((dA_cs_last - dA_cs_m), 0.0)) + scale = tl.exp(dA_cs_last - dA_cs_m) else: seq_idx_m = tl.load(seq_idx_ptr + offs_m * stride_seq_idx_seqlen, mask=offs_m < chunk_size_limit, other=-1) seq_idx_last = tl.load(seq_idx_ptr + (chunk_size_limit - 1) * stride_seq_idx_seqlen) - # scale = tl.where(seq_idx_m == seq_idx_last, tl.exp(dA_cs_last - dA_cs_m), 0.0) - scale = tl.where(seq_idx_m == seq_idx_last, tl.exp(tl.minimum((dA_cs_last - dA_cs_m), 0.0)), 0.0) + scale = tl.where(seq_idx_m == seq_idx_last, tl.exp(dA_cs_last - dA_cs_m), 0.0) acc *= scale[:, None] x_ptrs = x_ptr + (offs_m[:, None] * stride_x_seqlen + offs_n[None, :] * stride_x_hdim) @@ -641,10 +634,8 @@ def _chunk_state_varlen_kernel( b = tl.load(b_ptrs, mask=(offs_k[:, None] < chunk_size_limit - k) & (offs_n[None, :] < dstate) & (offs_k[:, None] >= start_idx_cur - k), other=0.0).to(tl.float32) dA_cs_k = tl.load(dA_cumsum_ptrs, mask=offs_k < chunk_size_limit - k, other=0.0).to(tl.float32) dt_k = tl.load(dt_ptrs, mask=offs_k < chunk_size_limit - k, other=0.0).to(tl.float32) - # scale = tl.where((offs_k >= start_idx_cur - k) & (offs_k < chunk_size_limit - k), - # tl.exp((dA_cs_last - dA_cs_k)) * dt_k, 0.0) scale = tl.where((offs_k >= start_idx_cur - k) & (offs_k < chunk_size_limit - k), - tl.exp(tl.minimum((dA_cs_last - dA_cs_k), 0.0)) * dt_k, 0.0) + tl.exp((dA_cs_last - dA_cs_k)) * dt_k, 0.0) b *= scale[:, None] b = b.to(x_ptr.dtype.element_ty) acc += tl.dot(x, b) diff --git a/mamba_ssm/ops/triton/ssd_combined.py b/mamba_ssm/ops/triton/ssd_combined.py index bbf4ecf84..58a6e04a9 100644 --- a/mamba_ssm/ops/triton/ssd_combined.py +++ b/mamba_ssm/ops/triton/ssd_combined.py @@ -20,12 +20,9 @@ try: from causal_conv1d import causal_conv1d_fn - from causal_conv1d.cpp_functions import causal_conv1d_fwd_function, causal_conv1d_bwd_function, causal_conv1d_update_function + import causal_conv1d_cuda except ImportError: - causal_conv1d_fn = None - causal_conv1d_fwd_function = None - causal_conv1d_bwd_function = None - causal_conv1d_update_function = None + causal_conv1d_fn, causal_conv1d_cuda = None, None from mamba_ssm.ops.triton.ssd_bmm import _bmm_chunk_fwd, _bmm_chunk_bwd from mamba_ssm.ops.triton.ssd_chunk_state import _chunk_cumsum_fwd, _chunk_cumsum_bwd @@ -50,13 +47,6 @@ def init_to_zero(names): return lambda nargs: [nargs[name].zero_() for name in names if nargs[name] is not None] -def rearrange_and_update_stride(tensor, pattern=None, dim=2): - # ensure tensor.stride(dim) is a multiple of eight after rearranging according to pattern, - # if not call contiguous(), rearrange only if pattern is not None - tensor_rearranged = rearrange(tensor, pattern) if pattern is not None else tensor - return tensor_rearranged.contiguous() if tensor_rearranged.stride(dim) % 8 != 0 else tensor_rearranged - - @triton.autotune( configs=[ triton.Config({'BLOCK_SIZE_M': 128, 'BLOCK_SIZE_N': 256, 'BLOCK_SIZE_K': 64}, num_stages=3, num_warps=8, pre_hook=init_to_zero(["ddt_ptr"])), @@ -130,13 +120,11 @@ def _chunk_scan_chunk_state_bwd_dx_kernel( dA_cs_last = tl.load(dA_cumsum_ptr + (chunk_size - 1) * stride_dA_cs_csize).to(tl.float32) if not HAS_SEQ_IDX: - # scale = tl.exp(dA_cs_last - dA_cs_m) - scale = tl.exp(tl.minimum((dA_cs_last - dA_cs_m), 0.0)) + scale = tl.exp(dA_cs_last - dA_cs_m) else: seq_idx_m = tl.load(seq_idx_ptr + offs_m * stride_seq_idx_seqlen, mask=offs_m < chunk_size_limit, other=-1) seq_idx_last = tl.load(seq_idx_ptr + (chunk_size_limit - 1) * stride_seq_idx_seqlen) - # scale = tl.where(seq_idx_m == seq_idx_last, tl.exp(dA_cs_last - dA_cs_m), 0.0) - scale = tl.where(seq_idx_m == seq_idx_last, tl.exp(tl.minimum((dA_cs_last - dA_cs_m), 0.0)), 0.0) + scale = tl.where(seq_idx_m == seq_idx_last, tl.exp(dA_cs_last - dA_cs_m), 0.0) # Might be faster to just do 1 iteration with larger BLOCK_SIZE_K, up to block size 128 # However, we're getting error with the Triton compiler 2.1.0 for that code path: # Unexpected mma -> mma layout conversion @@ -182,8 +170,7 @@ def _chunk_scan_chunk_state_bwd_dx_kernel( cb = tl.load(cb_ptrs, mask=(offs_m[:, None] < chunk_size) & (offs_k[None, :] < K_MAX - k), other=0.0) dout = tl.load(dout_ptrs, mask=(offs_k[:, None] < K_MAX - k) & (offs_n[None, :] < hdim), other=0.0) dA_cs_k = tl.load(dA_cumsum_ptrs, mask=offs_k < K_MAX - k, other=0.0).to(tl.float32) - # cb *= tl.exp(dA_cs_k[None, :] - dA_cs_m[:, None]) - cb *= tl.exp(tl.minimum((dA_cs_k[None, :] - dA_cs_m[:, None]), 0.0)) + cb *= tl.exp(dA_cs_k[None, :] - dA_cs_m[:, None]) # If we don't have the (k + offs_k[None, :] < K_MAX) mask, for indices outside this range, # we might have dA_cs_m = 0.0 and dA_cs_k very negative, and tl.exp will return inf. # Multiplying with cb, which is 0.0 outside the range, will make the result NaN. @@ -789,7 +776,7 @@ def forward(ctx, zxbcdt, conv1d_weight, conv1d_bias, dt_bias, A, D, chunk_size, zx0, z, xBC, dt = torch.split(zxbcdt, [2 * d_nonssm, dim, dim + ngroups * dstate * 2, nheads], dim=-1) seq_idx = seq_idx.contiguous() if seq_idx is not None else None xBC_conv = rearrange( - causal_conv1d_fwd_function(rearrange_and_update_stride(xBC, "b s d -> b d s"), + causal_conv1d_cuda.causal_conv1d_fwd(rearrange(xBC, "b s d -> b d s"), conv1d_weight, conv1d_bias, seq_idx, None, None, activation in ["silu", "swish"]), "b d s -> b s d" ) @@ -863,8 +850,8 @@ def backward(ctx, dout, *args): zx0, z, xBC, dt = torch.split(zxbcdt, [2 * d_nonssm, dim, dim + 2 * ctx.ngroups * dstate, nheads], dim=-1) # Recompute x, B, C xBC_conv = rearrange( - causal_conv1d_fwd_function(rearrange_and_update_stride(xBC, "b s d -> b d s"), - conv1d_weight, conv1d_bias, seq_idx, None, None, ctx.activation in ["silu", "swish"]), + causal_conv1d_cuda.causal_conv1d_fwd(rearrange(xBC, "b s d -> b d s"), + conv1d_weight, conv1d_bias, seq_idx, None, None, ctx.activation in ["silu", "swish"]), "b d s -> b s d" ) x, B, C = torch.split(xBC_conv, [dim, ctx.ngroups * dstate, ctx.ngroups * dstate], dim=-1) @@ -913,14 +900,10 @@ def backward(ctx, dout, *args): else: doutproj_weight, doutproj_bias = None, None dxBC_given = rearrange(dxBC_given, "b s d -> b d s") - dxBC_given_update, dweight, dbias, *_ = causal_conv1d_bwd_function( - rearrange_and_update_stride(xBC, "b s d -> b d s"), conv1d_weight, conv1d_bias, - rearrange(dxBC, "b s d -> b d s"), seq_idx, None, None, rearrange_and_update_stride(dxBC_given), False, ctx.activation in ["silu", "swish"] + dxBC_given, dweight, dbias, *_ = causal_conv1d_cuda.causal_conv1d_bwd( + rearrange(xBC, "b s d -> b d s"), conv1d_weight, conv1d_bias, + rearrange(dxBC, "b s d -> b d s"), seq_idx, None, None, dxBC_given, False, ctx.activation in ["silu", "swish"] ) - if dxBC_given.stride() != dxBC_given_update.stride(): - dxBC_given.copy_(dxBC_given_update) - else: - dxBC_given = dxBC_given_update dxBC_given = rearrange(dxBC_given, "b d s -> b s d") return dzxbcdt, dweight, dbias, ddt_bias, dA, dD, None, dinitial_states, None, None, None, None, drmsnorm_weight, None, doutproj_weight, doutproj_bias, None, None, None diff --git a/pyproject.toml b/pyproject.toml index 5831fe66e..ab6315c33 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,12 +12,11 @@ license = { file = "LICENSE" } # Include a LICENSE file in your repo keywords = ["cuda", "pytorch", "state-space model"] classifiers = [ "Programming Language :: Python :: 3", - "License :: OSI Approved :: Apache Software License", + "License :: OSI Approved :: BSD License", "Operating System :: Unix" ] dependencies = [ "torch", - "triton", "ninja", "einops", "transformers", diff --git a/setup.py b/setup.py index 32d62ed90..3ee91645f 100755 --- a/setup.py +++ b/setup.py @@ -172,29 +172,22 @@ def append_nvcc_threads(nvcc_extra_args): "Note: make sure nvcc has a supported version by running nvcc -V." ) - if bare_metal_version <= Version("12.9"): - cc_flag.append("-gencode") - cc_flag.append("arch=compute_53,code=sm_53") - cc_flag.append("-gencode") - cc_flag.append("arch=compute_62,code=sm_62") - cc_flag.append("-gencode") - cc_flag.append("arch=compute_70,code=sm_70") - cc_flag.append("-gencode") - cc_flag.append("arch=compute_72,code=sm_72") cc_flag.append("-gencode") - cc_flag.append("arch=compute_75,code=sm_75") + cc_flag.append("arch=compute_53,code=sm_53") + cc_flag.append("-gencode") + cc_flag.append("arch=compute_62,code=sm_62") + cc_flag.append("-gencode") + cc_flag.append("arch=compute_70,code=sm_70") + cc_flag.append("-gencode") + cc_flag.append("arch=compute_72,code=sm_72") cc_flag.append("-gencode") cc_flag.append("arch=compute_80,code=sm_80") cc_flag.append("-gencode") cc_flag.append("arch=compute_87,code=sm_87") + if bare_metal_version >= Version("11.8"): cc_flag.append("-gencode") cc_flag.append("arch=compute_90,code=sm_90") - if bare_metal_version >= Version("12.8"): - cc_flag.append("-gencode") - cc_flag.append("arch=compute_100,code=sm_100") - cc_flag.append("-gencode") - cc_flag.append("arch=compute_120,code=sm_120") # HACK: The compiler flag -D_GLIBCXX_USE_CXX11_ABI is set to be the same as @@ -363,7 +356,7 @@ def run(self): url="https://github.com/state-spaces/mamba", classifiers=[ "Programming Language :: Python :: 3", - "License :: OSI Approved :: Apache Software License", + "License :: OSI Approved :: BSD License", "Operating System :: Unix", ], ext_modules=ext_modules, @@ -378,7 +371,7 @@ def run(self): "packaging", "ninja", "einops", - "triton", + # "triton", "transformers", # "causal_conv1d>=1.4.0", ], diff --git a/usage.md b/usage.md deleted file mode 100644 index 1b588ce2c..000000000 --- a/usage.md +++ /dev/null @@ -1,43 +0,0 @@ -# Mamba adoption - -We've been very happy to see Mamba being adopted by many organizations -and research labs to speed up their training / inference. -This page contains a partial list of places where Mamba is being used. -If you'd like to add links to your organization / product / codebase, please open a -PR or email us. We'd very much like to hear from you! - -## Large language models and multi-modal models - -- [Tencent's Hunyuan-TurboS (560B)](https://arxiv.org/abs/2505.15431) - -- [Nvidia Nemotron-H (8B, 47B, 56B)](https://research.nvidia.com/labs/adlr/nemotronh/) - -- [AI21 Jamba (398B)](https://www.ai21.com/blog/announcing-jamba-model-family/) - -- [TII Falcon-H1 (34B)](https://falconllm.tii.ae/falcon-h1.html) - -- [IBM Bamba (9B)](https://research.ibm.com/blog/bamba-ssm-transformer-model) - -- [Mistral's Codestral (7B)](https://mistral.ai/news/codestral-mamba) - -- [Nvidia Mamba-2 Hybrid (8B)](https://arxiv.org/abs/2406.07887) - -- [Microsoft Samba (4B)](https://arxiv.org/abs/2406.07522v1) - -- [TII Falcon-Mamba (7B)](https://falconllm.tii.ae/tii-releases-first-sslm-with-falcon-mamba-7b.html) - -## Inference frameworks - -- vLLM - -- Nvidia's TensorRT-LLM - -## Hardware - -- Nvidia GPUs - -- [AMD GPUs](https://rocm.blogs.amd.com/artificial-intelligence/mamba/README.html) - -- [AWS Trainium 2](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/general/nki/tutorials/fused_mamba.html) - - From 4ea3e20d0d51928b48b3e9299dcb7eabf3f78185 Mon Sep 17 00:00:00 2001 From: maxmelichov Date: Mon, 25 Aug 2025 10:41:24 +0300 Subject: [PATCH 07/10] Update .gitignore to exclude virtual environment directory and enhance README.md with comprehensive setup instructions, experiment details, and citation information for Differential Mamba. --- .gitignore | 3 +- README.md | 200 +++++++++++++++++++++++++++++++++++++++ figures/LensLogScale.PNG | Bin 0 -> 215578 bytes figures/babilong.PNG | Bin 0 -> 84244 bytes figures/diffmamba.PNG | Bin 0 -> 96338 bytes 5 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 figures/LensLogScale.PNG create mode 100644 figures/babilong.PNG create mode 100644 figures/diffmamba.PNG diff --git a/.gitignore b/.gitignore index dbde1b117..be627d6c2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ build/ **.so *.hip -*_hip.* \ No newline at end of file +*_hip.* +venv/ \ No newline at end of file diff --git a/README.md b/README.md index bf3b76a93..f21a90b65 100755 --- a/README.md +++ b/README.md @@ -1,3 +1,203 @@ +# Differential Mamba + +

+ +Nadav Schneider, +Itamar Zimerman, +Eliya Nachmani + + + +This repository contains the official PyTorch implementation of Differential Mamba paper. +We also provide training code, evaluation code, and model checkpoints to reproduce the results in the paper, including all the baselines. + + + +

+
+ +# Setup +## Clone Project +``` +git clone https://github.com/nadavsc/Diff-Mamba.git +cd Diff-Mamba +``` + +## Create Environment +To set up our environment, please run: +``` +conda env create -f environment.yml +conda activate diffmamba +``` +Note: this should include all the necessary packages to run all the training and evaluation scripts. Nonetheless, make sure the additional requirements are satisfied: + + +Mamba Installation: +``` +pip install causal-conv1d==1.5.0 +pip install mamba-ssm==2.2.4 +``` + +## Additional Requirements - Language Modeling + +Install the requirements in: https://github.com/state-spaces/s4 + +In order to train/evaluate the Language Modeling task, first, download the data. This can be done using the following scripts: +``` +python language_modeling/src/data/datasets/get_wt103.py +bash language_modeling/src/data/transformer-xl/enwik8/get_enwik8.sh +bash language_modeling/src/data/transformer-xl/text8/get_text8.sh +``` +Then, move the resulting datasets into language_modeling/data directory. + +## Additional Requirements - Retrieval + +Install the requirements in: https://github.com/booydar/babilong + +To fine-tune on PG19, please make sure to download the dataset according to the instructions at [deepmind/pg19](https://huggingface.co/datasets/deepmind/pg19) or use the Huggingface dataset version. + +## Additional Requirements - Tuned-Lens + +Install the requirements in: https://github.com/AlignmentResearch/tuned-lens + +Make sure to download The-Pile validation set to train the lens. +Locate the .json or .txt file in the directory tuned-lens/data. + + + +# Experiments +## Language Modeling +Run cd language_modeling. +Then, run the following: +``` +python train.py experiment=lm/diffmamba2-text8 trainer.devices=[0] model.dropout=0.5 loader.l_max=512 train.seed=0 trainer.accumulate_grad_batches=1 loader.batch_size=50 model.n_layers=12 model.d_model=1024 trainer.max_epochs=40 trainer.precision=32 +``` + +```trainer.devices```: used to determine the GPUs for training. [0] use cuda:0 while [2] use cuda:2. [0, 2] will use cuda:0 and cuda:2 with DDP training, while 2 will choose the first two gpus available (cuda:0 and cuda:1). + +```loader.l_max```: the max length or context window for the current training + +```model.n_layers```: determine the model size + +```optimizer.lr```: to change the learning rate, otherwise, use the default + +```trainer.max_epochs```: number of epochs + +```loader.batch_size```: represent the batch size + +```model.dropout```: the dropout of the current model + +```trainer.seed```: responsible of the training seed + +```accumulate_grad_batches```: can be used if the memory in the GPU is not sufficient for the required batch size + + +## Retrieval + + +Run cd retrieval. +To evaluate the models, make sure to save the models checkpoints in the Diff-Mamba/outputs directory. + +### Finetune PG19 +To finetune Mamba on PG19 run: +``` +torchrun --nproc_per_node=4 finetune_pg19.py --model_id=AntonV/mamba2-370m-hf --lr=3e-4 --batch_size=6 --grad_accum_steps=12 --max_steps=4000 --weight_decay=0.1 --warmup=400 --save_steps=500 --eval_steps=500 --output_dir=./outputs/mamba2-370m-pg19-finetune +``` +To finetune Diff-Mamba on PG19 run: +``` +torchrun --nproc_per_node=4 finetune_pg19.py --model_id=AntonV/mamba2-370m-hf --diffmamba --lr=3e-4 --batch_size=6 --grad_accum_steps=12 --max_steps=4000 --weight_decay=0.1 --warmup=400 --save_steps=500 --eval_steps=500 --output_dir=./outputs +``` + +### Finetune BABILong +To finetune Mamba on BABILong run: +``` +torchrun --nproc_per_node=1 finetune_needle.py --ckpt_path=./outputs/mamba2-370m-pg19-finetune --lr=3e-4 --batch_size=6 --grad_accum_steps=1 --max_steps=500 --weight_decay=0.1 --warmup=50 --save_steps=100 --eval_steps=100 --seed=0 --output_dir=./outputs/mamba2-370m-needle-finetune +``` +To finetune Diff-Mamba on BABILong run: +``` +torchrun --nproc_per_node=1 finetune_needle.py --ckpt_path=./outputs/diffmamba2-370m-pg19-finetune --diffmamba --lr=3e-4 --batch_size=6 --grad_accum_steps=1 --max_steps=500 --weight_decay=0.1 --warmup=50 --save_steps=100 --eval_steps=100 --seed=0 --output_dir=./outputs/diffmamba2-370m-needle-finetune +``` + +```--nproc_per_node```: choose number of GPUs for DDP training + +```--grad_accum_steps```: this variable is used to increase effective batch size under memory limitations + +```--diffmamba```: this is a flag that has to be chosen when training Diff-Mamba + +```--model_id```: this is the mamba pretrained model loaded from Huggingface + +### Evaluate + +To evaluate a model on the different tasks and context lengths run: + +``` +bash scripts/run_activation-beacon-diffmamba2-370m-needle-finetune-seed0_no_instruct.sh +``` +or +``` +bash scripts/run_activation-beacon-diffmamba2-370m_pg19-finetune_no_instruct.sh +``` +Results will be saved in the directory scripts/babilong_evals. + +### Plot +To plot the scores, simply run: +``` +python plot.py --model_name diffmamba2-370m-needle-finetune-seed0 --results_folder scripts/babilong_evals/diffmamba2-370m-needle-finetune-seed0 +``` +To plot the relative percentage run: +``` +python plot_compare.py --model_name diffmamba2-370m-needle-finetune --ratio +``` +The plot will be saved in scripts/babilong_evals. Use the flag ```--ratio``` for the relative precentage plot or omit it for the original scores plot + +## Tuned-Lens + + +Run cd tuned-lens. +### Training Lens +Then to train lens for mamba, run: +``` +python -m tuned_lens train --model.name ../../../outputs/mamba2-370m-pg19-finetune --data.name data/valid.txt --per_gpu_batch_size=1 --ssm --output my_lenses/mamba2-370m-pg19-finetune +``` +To train diffmamba, specify the correct path to the model and change the required output directory. +To train the lens in a distributed fashion, change ```--per_gpu_batch_size``` to the number of available GPUs. + +### Evaluate +To evaluate run: +``` +python test_babilong_0k.py --ckpt_path ../../../outputs/mamba2-370m-needle-finetune +``` +add ```--diffmamba``` flag if using Diff-Mamba. + +You can stop the test early when using the flag ```--num_examples```. The compatible lens will be loaded from the my_lenses directory. + +### Plot +To plot the results run: +``` +python plot_tuned_lens.py --diff_results_path results/diffmamba2-370m-needle-finetune-lens_eval.txt --mamba_results_path results/mamba2-370m-needle-finetune-lens_eval.txt +``` +Use ```--log``` to create a log scale plot and ```--start-layer``` and ```--end-layer``` to choose specific layers to plot. + +## Acknowledgements + +All model implementations are based on [Mamba](https://github.com/state-spaces/mamba). Training and evaluation for the language modeling experiments are based on [S4](https://github.com/state-spaces/s4) repository. Evaluation on BABILong is based on [BABILong](https://github.com/booydar/babilong) repo, and measuring signal-to-noise ratio through the layers is based on [tuned-lens](https://github.com/AlignmentResearch/tuned-lens). + +## Citation + +If you use this code, please consider citing the following: + +``` +@misc{schneider2025differentialmamba, + title={Differential Mamba}, + author={Nadav Schneider and Itamar Zimerman and Eliya Nachmani}, + year={2025}, + eprint={2507.06204}, + archivePrefix={arXiv}, + primaryClass={cs.LG}, + url={https://arxiv.org/abs/2507.06204}, +} +``` + # Mamba ![Mamba](assets/selection.png "Selective State Space") diff --git a/figures/LensLogScale.PNG b/figures/LensLogScale.PNG new file mode 100644 index 0000000000000000000000000000000000000000..3d714a49102683d7ae781b7151d25d1a016d890c GIT binary patch literal 215578 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ℑ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 s1&t&D&f$N@J5*)a{y#-nY%ovm9_4+~X8UH||9 literal 0 HcmV?d00001 diff --git a/figures/diffmamba.PNG b/figures/diffmamba.PNG new file mode 100644 index 0000000000000000000000000000000000000000..e297080c71b317cd2182a1390a0ebc39f0288b25 GIT binary patch literal 96338 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%0ADD(#Zv* zuSQAFOBc;e0E*pIB<0B5lDS5iLd@0k$?99tgYVQzlS=XWp0grLxp=C}L8Wm;I(2cMGoc;g%7w2EB+{9?((3BTXTZ>NsTqRL2X;BuKxS5LwFLHt*!+8uzT-Kc7^xjng0E5QNQvwidI!&6ILW%5 zZ8Xr+9QV`acOEaga>pWV44%oTIblSZC#@{Mbq?>9+}Ij;LAAlNyKPd7%Pm9sfe?{FWT?$Y8#h7T**l z20!^R*O;=L-{W~j6Gm=DW-2{>@&Q+OzeZ4xNZ-LXO=-?Qi^BG>6Gm-Okb*vQlaHoO znw%$sMgh68l}Syb1%(yoeOx4y!$?{#zW6vfjItMIqaXU@S{d5?>Q%-#?`4AuiJhYfW()qU36%yPTL!DwN0dtY4U{mX?9>Z4c zkJT#k>1~;CpJblg8`-TPQj39PF$dZdJvVs*gwUnv$Ua1p?l%bn!qez-Iy%(jlzV@Y zql(uobx<$yN|p7mOL&`Bt}geTuC|K^bz?8hS@*mEudE;Ok5|S{pMv5SXFJp->tk+u zMD)%#X?-|L&(^g?s9B2yZdwZ#jk&P-7FtY-mI)V>5GDO+Yh;rT?yq`^wKRZOYl{Vm zZmqf5-NGa;jM~cVtb7eJf*Ve2?dp1Y`xM{WgKw){98dd695Ze_ur7Cey)`b)TYIk5BNQqW z%y?KVpTj1pmw)PG$eM}JyRh$?CqsT2lM%l&gZNPy{61`SKU9lv>Vb0wQ#(2!cuM#* zwZ^~$K0t70warYyYZ5G$zYZ53h) z4i}Tyme7ITay>D*$LLH}$`szvKC;=?imH2f^Funs7Fv+a%a7GMTdyHHa<0=t>O#Rsq|SkN2wCV56B*E1T$(j0+$ zWUiP)UKeqr=clDg)n5X`@+#^Mo`-83T7Um^F?&{6lUrUPUe#dJ+r1smJvb{{Gj6TJ z$~Z-EepQ)?zp2*7tvY{QE5I{XSvanrvrZ|{^WYGQPvxlR&HVyDulPc<(QQ1(L;96) z{AHidYpjRt2U81+y^0@g@~SIpA{R#+wUJ%Z`{*uQcZs9TceI{S0-|#pwa-|qip0BV z-{YwKh*pCEo|$TkW9zv|<*v*3Dw22T7{_um#?lA|wT=B@sCm3hBtD+b{CG8n>*Ov2 zcD<7~obDuO*G}icvQWG(X!Yd`49TZu-RAMb-l8|C`-rLHgD;@EsotS{N9Jbo>&xhu zbr+E8?3w<71{v~Jl2AnJptRLio-X4{&tpS+^>89m2D7-?J~2Qm05c=lRSbu#&h*og z$8p;Q^L343c`}I-J|)A+q&LVV`TeFuFLI`QvX8Kv29Ik~Rem`xgzD1KRwZ~*wV&c( zFUaY#cQ9AMxbYm#3VD(_I}5%0xf5l@wppt#0ig*$yZ}sAQ08 zYhe0}gyD|_EP;zhy=b3WGJA)@GxAaf@!(l#xVA~AV63-NUrkP<9*fyPfx3Ce4~EDx zHnQVE{`UbjgOeMjTq$!?Ief{{e&p!|Z23@fC|w_0|B%vqBqyp%E&;1rIo74hO^B&s zWBqvy&xSlC7PQ{H;0jS$j{$}ZM#vRppp$jCI76ja=8k(|$g>!R#YW+~Q33K}r1-BK z2)HsS=wZdBu&4$dn3oDQOdk$Rv>GaJh!>W~ntV?m!{)`{ZoNu3p7p=e<#aNY%b}?3 zauOe6luoV%4zDU=0mTvz%EAG`z7GVz9XY!LChsMdaSYpWlz|lQk({o19i_rK{0a1s zhh(DSx0oTpnQjpY+Aq#p012`87vR&1q&ld(+v3u%R@sY<+92ixJ;ONNC8m+oQC9p! z>iNk&8Zvmw5$R3gmkrkzP|zWG*;_sYET(Z5cv|pgd|vmMLd~=yx}CG!$F!>h`1WsP?$&%BqI8 zX+Bx7TJb1OP?I_E)pf0@$s07{PwL0sDv>_nOjz^@u_{3>Yw41SmJ>DELpFQ8WGUtu zS6nSJ+P(c0R)!IkfgbDlD)5bjo21=nHbWBA^+qsYjf)eGe3ZRlu};s|CnE@aSbJQ{ z_RjCXF3jpq@t!_6Op+_)x{Hht>rHv7sbADO&TXNbiU?9*I6QLG8HgR5Kv> zN1ooIA#$zBbHuG z3a!Gr@xIYc^Nf@ACC9whP_U*1tE`c)*s_e)aH@$jMo53H+G<=t?T{Cw4G}IH|Mto`H5+k%k zG-=@rqUGntB2|%29lVFhtSA6B=Q!iAa7xv3r9RW@s;WRSWFNX#8}1iyBsz#70gp{& zd=odf_?nlK6*K%Ll2UZTOrAu5IX%Al?U)f7uhk+Z`3}m03@SQJ7xt}so_J*RbI000 zvCl%P=C}XC97U4#Z!{}VrBUw73afK(*^TOvyG-j1@H^9++`_*>(pZ;QvanpBFuX4;t6MyjM3y?=Q1oX1Ou=n%6 z_%O4tzsH*mU-q25wc%qm-j{|DO=v@*b#L;O33Pzmufb$BA0EhJ!E3ErHN~`h47QCK zSz(9bVc7MkIAwc;%Z@sk4U?FDbL0T8s{o>f5T#e?5=VO!g1KzJshqql)M?CuRmiwv zBMAPO3rf%ty>QB5UjF>oVckX7DeD~k)NS?)GcUh)`l zzX4@i9~@xT0JvqbGYxQQtf0AA1c`TX;2?%g7e_LP}g zM~OGb){z9#3x*>?&@}t4$-^NmMa#ni+Scn&^BQ}XtZ{|x#>X6&>F8jp!v7CvZyi-- z*Yyia=cYl}w19MPTDrTtyG4+a&P^-bNJzIxcY^|ggtRmgBHeW^(EE9x=ZyEf=R4ou zdyH$ZS-+WUt}TkKwL{PK2bdfl+@(=0dl2_bKn9%uEqi&mBz zga7!>=vuj#$iI6;e<4J>w}JghA1V6l6R&Iw1Mx&Qx=~R3K1>9TAD;9Wg(2Gk#7C|m z1qY@5i6Ov{@5*cH@4cq5rr6U&C}HKTi^rDZLhHo_=W`QZznh!iuNu#YjwxIl zbAAJXl7fb2?xzg1rua_FHKu0|V{jJ8Cqr4n#hfXm?lJ}9$qc`VRsz^bE}TBUt1?Wd zxRWA*CD`({T&L6OZRj|N43MlkU)!J2_Qj)-OI~|RflY$wEVGUbRD}W(Q)$8082D9y zr}h%Gzl8{G6l*c7?&X`<7fqv5pl`ItHu~p2=NepzSSwIn3#1&U) zY!x>AG9M4FE&Y^1wUKKylhsQ5nKks|R`D_uu=GwEVG!cZHUQo5c~T$EO9gQ7qB2y)~$m8{;QTeR$oM+{LbB_4QizF-jl*7i1Y9a zEH8hYBOWjrEJzX-G$~`^Sog+>N1Ry{&ePW#(LWbTfkfh+lUkTO-J(6Y+#1GYXBTY& zmXw(f<;Ez7g<0#_HOIhHA{}pRAvJ3c9fX*|gk>A^eP4w$7RwXM5%rR~Be^fZQf~Fb z4mK#2?xboG=^JHTRc{U8doe59b9U<4l$QZ3qqknglod4P;ZXB>PZaGHgqqZP=5%TDc6y#m7exoW|C6`h9p!!VSH z&hHn)xA$^v&5sikcAXd_GjyJ%2N%o+=j$+@xWL8k!Ex)SQ10I*S)#)NB2^I4F?g9H zag|Y`jCDfaLuv9=zxowrzVBDD;hT0lDdvUd&n`xLSlPc9`#=!+G?ZUMwk*cl`is`f z3bXg}f0=v@l0d2o@x)&k>j&A9QIELJlt<|Ov$O>VehS@&4T2Lx^GPrB`}*xC zeI#Lj7)i~uss6kaC{}7wpD!Z0$q*iz@;Lom?5zh^NxX)@YTogcNx=(j;iT;EM-;J$ z%yCnHc5$e2qeQp5xh7Q6u|U9^c?T3jV8)(IzA|PqzTu{RDuK*tp(W%>_wBve>6der zs`gpn+If30dO7UvE>9)~jS(rU0-Y7JP@LuFMVb|8)#Ci~KBl4xx zUE~SjlMP&{+^~h|d4cTwjvNY`&S+2$w6`;g`k6(n`l;91RjAJw!-g-oK#0O}1*4^+ z4t`%6L%d!NU8Bhqa@OGEV-Ww#fke0m4h&Y_ms^q47yWYB@ezpXb+LT79ub+>_1qr` z)mqynncAw&gCfr%aW;ugT}&-XWsXD;gbh)_fOS1Pc>03O%kDG;9_GBwpUixg1`Fm5 z{)+%aa%Kk;i6FCIWT$I%3EwKyj?Dj9zNbHuIwp#Vg_ zgL@&+4=T~I%pd`$rPckFYx2Wzm?b}zpP3}fDo4n9c<~q%-)2+ ztI}7X z?oW@8jjQ&}tP3X~r#NA$#AU8N9rE~ot+Vb$_IIjkrWTkw+PP&RZ-=W>h7&YaV83F+ zCtjCs^!!l-rv@~ZA)OfTctEMHZ4?eu9M4n;hY!9wSHhcta@niEropEaMgU^|VOe#B z$D@6jb>tox6|_D!dJ?~o=!m1(dVM>}S}Wf(-Rh*SwWnbuGUVLGuAsiMi`l-xXhZ|=KFl;>Tq845qPs=fC24R1PVFZ6)>x8pDf?AH615G9u%H3| zHvjuO&wDF^e08To7g(}W)DYDfm;{A>{_Zzpy!g*%nr`ON$355Qc1vnhIJ~#eB zVTb~k`i|(6xpgcD*_Ax=`E=jJwDR>2o(Lkgg22kKQ%7W5hdPU@?!~8U+j}=Nfw6#jM_$DQs&)Lzo>tZjX*?kN<&wiM2%7miQA&HT4RHm}DX~W)^Ovp7v2POGIzcs_Z?tS+*IGsRId3k){}dbuFZi z6?kv=TZ>#(_E*b66yJzAo=tN2DN|8wl`QdFMn({XU7H{+;LAkI%U7|>l#%U7TUqa; zC0C7`3||MFx!&I01*Mv=4)}n}%T7GW+2qr)k90uR6*3bfRU(|s)YZF7)8xz z9Xgg0ZH_i8J@lyrZ0tLaEnAuCcdIu6MBp$Vwb{{QCvJMo0MHq}f=achk`1rX)%KeY z`=@b^e*?hc^jY29uAc}XHF=FPL>z8Rk2s~pOV`$Sd}1CL_hd-ShUSTrVajXdPnd=K z(U$N>5`%+_2YKVl9ge0`i5FHsA!>!a&k5!w9iTuOUuGQ`$hH_Jml`_=zIpHD7oB^v z|J3MlNIfS)zTdO=a&lw1`;`)$D9kDA4T4teE74mSizg={akcX8)DnU6?WpnBm<;Z3 z&k{@J51)vuGrdovEKpo~jE=Fk2*uIDPAtoxpAYS&90Vxa1Eb>i!j{!=F_8p#4BC?U zGn2b&Oigv_TS_V)ecEG8O{X%UYdt*&;qv*wOq7iz^w%%?V*w}8fYyWUKpc|wP|*|~ z8A{CQi&fe}>omarH+R12eQyvDW#7Cq9iYv;V9!P*)|6=(dTxnCd#bQu0JXuOeg(XX zzFLqhJJkS9w%^bNW?`7Qr%<+fq1k>7t2t7ldGBx53;J)u7QCpjTu<6P2x|FZqY;;q zUyx|NpFTno-8Kld@6+(KFO~>x8jXjGOedm=)pQq+!Bym4V-CuRUAKW~sPV}S-~|Wd zh~m&ab?TS7JNrrwJwL?R_2lRDU3mM-8I=OAFzveal$)i~>21Q_C@#*3M-+}SK zIn+4J7pbC_*f*Nav8wOSG)O-H;Axnp0q1VhkJvTz2H^-|pYDSEgcU}DOc_ooPy?5O z-nUT`t~N2VEs#RS7SsQR_d1H(4*942RbPk?+#GG~!S>z?rG~npjLr8W3b9RA)5L12 zt_lM~RDJSf`;nm5G>%JS3jKL1ViRfD?0}!iJ1Z^Ep^6HpaG}P}gmmd`e@jwu$VYgK zfIj#$8V8?nbgmrO5g}Sm#plGEh!270wQ2%@+4plSjm?8zV~_S6dCxMlW=ySwj3*-` zWAW+1xq_i5BpPBe_iqlkKfpx6K&ZVD! zFYm70uFR8u;-i$H=+M~OWKE#{L4{`7+)nbIx%JO58g5GT;cCr6cBXFXhV2vn*spN2 zr%1dM0eCxU?=46|*}7#uH#E&9e3X)e-JRlT`E&1wVoW*p{uJ@Ue%lY@BMi>tEj5-W zVNBaO_TcXYBV=2sPXb*u;h~0NxL%;PYxUR1Wjd5g?t{|Ez01mjiHQ`wVn)1*LL)sTz6sg*0#wD)!tEsHb*`rJZT!6Gv3E?%rxJ+mrTbEM&L#b>hKst? z4ArKY)ZFWx2Y;Qo@qPjxd{$SG&?}i3rI1Xz`ug#)AS7P9&NLP(cd;ki?#1o~k)bkv3P3;@YQf#MS^PzHnd19e2a5d@NHqRtECJ4&enF6b zaf;L3o&1O*2CC-A+V8CA+@AO6?K=zfV2wI>o7fGzSeebJPp%$c~zk&^5LTV&xVs5qQ>BM=4hAjH?RslGH>49;`rr#*>i zbs1CWLTPBlw3C5}6HdS*l4B_MTVRqYak<2@e>Q*8e4+*4^Y&6p>?~1|AaO+w#cLGU71uOA#2|b@Pz_~rG~{bv5Mf9| zVTzX>e%w#U4EUYuLI2>__lV|p@POoJKXT{`Yt)$m8(V891f2XrhQJQ%X+1qBoc%dV z^0;o9MiEafz00pMI;!E0UGVsq1Zeernx!TP*Qfjs*bzhQa)11d0 z{-d+RSd++^-?!bF4CnlB4pVOABsU`n&Gp*C48^+{tyfH&QJrw8wNg1PlbDfoXQJsI z{1{Jy!YBFPH+#qYhO&Buhj;IU*+k`IvJ0t2qe^{WZE5%V;tc^;0>@lwzHAm3DcfPo zWsuu6-pj*H`#8L6Q>(Slv|BE*s^o!jbHelC2On^2A$2DFj4hz&3Z+RgNM9?_(e)wL z2DGijC0xbVo;)RBM_H0jQ!~t#6@mWQi*H-Zlim%rK{_C6p&XEj$F2HuX za}Z^{kkRy2Yb5=*8qU8V=4=klyyC2@!?9htfoeJd`4O&SV|PJoY>5?xvvH!^j_*ln zNs9&z12Zs)N$2R76ZqxpYkJz^eIz$!-glS{KuSB!I~72h{!#T{yYTsGRN~fNv^X$o z9E>$59@mfg34i`wQda|e+M=*~e721!yQE*o*iTZ!Z+BmtY9hw1&)8hH3Gk1L7IU%B z=>1(Sqz8FFfEVyb0TDVf0(+uu=)y=LCgw^Kxd>OOwSX4|KTVvT&rXVcIRLpiIKQJ+ zC>FdqMjF$6hFI}AmrH6Tsp^1DH;D%Yr)(Jf1|Tsh=`V@#wxe3SiIYPbG`0sTdv|xV z9QrPLT5>oc47K9BYWpJv--*&oB?>}mfa;YS5~Oi0L`MM;1buFS*Gg%Gb#gyGLhYG! z$+%eghT(s?MsO zMD5rIjjM%;${df4@5Pi*xt=X1;eagZ_<;gT&u(4-$TM3WQ z(3uUWc-Mcl3o3ss#r(PP%OG{D4m`BQHYfXWFMCy#8^xX&F{Oo`l@;kdtv4#?=VKye z&hb@hjZ^lSR?_a6iW{@Q9i}C(>ga z=CooR`yO$v_7a}vii$hvMe?mqZLG4t;(T1Gn-2%h0^uP6?K_EsHavzbb?@=0;yWQF zv#Cq#K}tFXMmYs7?n@*h+YTMvLo)rUt8tkxFxV(6GL+Ba4MZ{$;YETw-UWZ*zBFPi zFPZ;)e>6QO0q~tP1v-tZb^ToS<(aQd04UKH`g2cQV~R*O`4@gB-h7}FhH7RXo)l9y zuPQ~RUfzY&U; z3Vvhct5WhSGTRh?CUxOEFK|t4ZD16%uiZi-#%(PTG4y3|A|Q=cXZ8jT_Kc@bW-vFb zBI_nMs`E0zVIFU-BJYqD$M&erYieuBf~J)D1ppDuw_pwmY_A3Ow)-R7OcJlpV~1iEX&?Q|!&L46v)Ydm3u6 zfK~;qfEwUXgUu3AYQ9i@nIxm3Wc>L~(bILkR41LXU?!`a+Ca=MI-*c$a4|n29=ZN- zYo%8|JuBXa{M*uuVGYg{LFVMM#N=@i+^4{vhWsS6T!0dqI=LVcIo;Retsd__Ksm}(lC!*)4<_jT+?Rtp&L=J z##Bq+@iCtp>Ca8NKRYDwGva74l`ZOck=_?EC(`#2YzGL?E7kE#ar^&c2MnNmuqfOq zj-9g7WlY5Jb3?|ucNp1Tm~PEw*f_END+jmNtPnIcQuvfwEW%~po1^I^idAOI4THvL zgVAj2h^b_=gkY^mE;$3OFsJL6J#zw`=sPEd&8oP{xJe!2_NH&tnBrpPqofB`sRAf$l#f(YOOh;%pw>n<))$ zi6pPL#?_1NUs|PJASeAOi-PSqqJS{^Kf5I9;9~7yL6G5!D?b;NwX>+t80n<}RYnG{ z*e=k*mY%7JjZJo7Iq>>i|GZW{g5x2Aqa`(Yj*th#Hz)>PFD_BTOD+y!*6Vr|MRKy> zpc-Gp-%3Tcz3p)BGRvLC0PBHaIJq&vSYjb-=6SsVvU)$3l-zsa1nVDuOcrGW+PAEE ze&5Te>h}4eV?+;vJQ8P+-q&xlDUxxNVcx(CR9f_yvsw8cwnJz*&r%K%t-gw{c%W`L zr}v=Qr%(yqg}y&R8Okt;wXPJYzE_ru^{-kSUVsL!4I7qro*K94JLlW`v-bWb$NBSl z-;Es>TjgyMkFV)7vc|7R#!uT8y{6}xFO90&HfMh~+}_`RhKo#QRt-RwrKaH<-ueq@f<@G0wg%J@=J+M-anmZ*z-8`Oz(F7nP8gttS6;q%piwf7-gFm@(Br zEb!Uk{d?a#|10@tuX4^uDs(#V6+9`r>Yv$ESOlixjrq_CR!GPY3D2ozT!~hR4@gJC&4#g5vMFr!myI;%c!mdJk;&Hph0;q-PnSS4@AagJ^F-5A(FWRC8 zO#Tjn)*%~|VyWiY=S5nx;6yd;8nM4Jv0$%IyWq5O;oKJMcFPu(m}h$Ve6H3+AG=no zMg#>sCo_`>ih8zp84b%hNr=!M;Jlj!gywu!&x&!FTAvGPrqzWY*Sos@CbBzT%>>4G%5OiR+~RY6Y^&sl%Ru&@6MwW4R#uw z`}1WzUXgcdX>G!DO0MVV0~cM6+6$elK(&-Y90hz6KCX%;txu|{v4EHqmy;_d`o1AJZ`|4~3__=|DQ2vdy5yUi zD_*UQg$IpTTBo2#CBlR1TYC(`B!MF>71s?!O*y)xZ;Ot-x-!7zFz`P5Nj~a#y|(Wp zaAkK_E4Rt?yNqFZ=|Lc!Pqm{mNgN%G+WzNH3EA)xiv!OjzS}KZtD=(8xzV9?B{;|5 zuwQ@$zM>*-H1f%%w(iXy4g`{tWyry#h69;7!gx*ks0|;!ld)5Jc z%rOt^a8F8aFD&@F`kuw;C&mNM`C;udQ$AG0F#dF?=?iC6xMp_fAIX<*Fg(wQ3O5`d zfp1};{s0dOSAnGteIzs%AasMDcck`JfKk2+qVG|HYwXJOZbu~|u~3Ja-L=5%lPK>R z*9zhX-rLER+giP?=dQ?bH*EromKnUJQT+Wcq4Gh+vYOLuCTie8j`;(ufGp-#9}N_l zsp$v98KI^Yewa5?kJVsIT%Rb4ON(y-6O41Z>1PzvF7@%4618lhs-RG}nFG)dl~`kG zYv=tiu~<{t*Ys(#zm?RV6rp*3kx=1HhtQGAnprujDI zYiD3wU#;ZIett-BA{xrHFD>>SXNcsN`e(zi?B=4!xx@81rsfB#YWxc5kLYniM0fzh zrDmbAjm3ke4_zSCB}t@cnAiS-gH=S7oQXwnLp}1NWIY3gh{8xl9O}>s^PHPRHKw|; z2z6Q>iRg^q#?#YUUcLC8#eRrE*^XLhI8NWj=(h4U#gBo!iL;!|h$QR7^oR4kS?m zhq`M6XO3G=H&fLF3O287h@_KB((GFyE912IZ{#LF?vPtJOCm#PHTDtqro%`2@af)$ z?t*u&3TFB_k4@u8v|gHHWn+Kuv-xRSuR+S$p6Sx&heOFXiuj`@vSNk@4h|M+)JVay z%~+0gN`DCr+4TdZO@6)FR7FgX*mF(eMmzO6^!>y65~Y z@F08LkQc9;Lh2pW2_8L#h{^VwivJrE4QSZLVxj2S*}lPiahqciuY5Fjo;X4K1dVE6 zG7MJdHzf``cofaUsu^ZY#pll{w1pNORVt{u)elpA^mU1!pKCx{u$HST z-EY2Fc0Q5~EiocCMna!%-329d7{u~dFYzu=#Q^(F{NC_KEB`m&9`r6hY~GINR2Yl< zhCPt%U}9-!iroJ;*Bp^lR$&tMzbGjZ?O{KuUy8mqy7z-#ewZo6O<|Bow80K+knMi! z6G^jc2oqen4B$hp?zEL1Lv*5W%1Vx}n+(L} zujr#VAFP_9di}pn#xMTg;EWITqU@yhr|zR;F0MeEm8;W=sUFV8LS?x&$$3-fcgf{h zK-6T*Lc=+~xZNM1p>184U-DetBiHD7;oKf=3j=b{X zY|ugtSaM^Vx)3atqymZTqG63ikw1Ki9KZTrpKeh1c9Ha2I6Q&2px5mA;L$>9(dkAK zAMcHO-7kjIK~1=_G>Nv?G8_wz$f#<Wk5KP7bInSkl}H&>%Dy^?|t{WRiQx942iwOnb&W^!*NC?lFy2shu8Fr z{4)!1a+ztp$_c()m;Wwk{Sd+F6&wuMGEmh0avPDO#Ct?sUhE3>^Q0?p+caH=l)GC- zRdW~IdZ~&ztq|QDc+mf(y<-bmN&ei1x7xmwB)Fh&T7%YFsS~SiF969y- zw(Bds48X^=N)}H?k7A**q3HETW=%~I95XK4%j*0nj*0H%CI<&$!Tk1P8JV9k!O1Fa zv}*c(PM;WbqU29kx9e66L+Fa&1c)ZXOH>@A#F(KIZCL!dj%h?9bO#f8-(=O=YwM>w z`Xjd;LnKlbhZIh)e$rk!53{jZV#2bnmxoUE+3PMtR@lM6ZPQbk#j*bp8IiyeM`@l6L#!hyFA5<{|M(yH*A7 zo~+sq(Hbu)c8G}FCiQm(~1s3{(zsdWtGp#9K^ z&LtICl@qCIDY?z^5~lA)+dKDgN9+k`?uF{k=p?=krx-(r)EMGifIrn6u_S&Jeke&i^@#}H-Xtt!_k{El1 z%qgv&(pHpAg?>z(1dXts-UAYm$0>mVq zo?KbJ@QuS0yuyo~%%J1CDVE8X^H;|kj{*pSw)UoHwHSzf(wi>$m$!1eE#Q<&D&Sar zKAFc0F79~Tn4&Z$XY=w(5nX>_7l7%LuO~ z4iBoHP-39>9KJ@(3o=)Z8Ij%jHt;>S!LT+SHAU9eke&h55fLUEUzzrqGuJqw2P$E2G?)b!^oUE7q%(4eo#^GtsM;3n3ohCWwZ>%v!1zVjc=s4+c zn*uXVJu0$nxPM4NEM#M>3H=>H_d4h#qr^C5=?fe}dtOLM<1_L7ms1afv?XAOj=_;q zZ(S^pTAVlRj<(ax+y2T?U%rt0I#fyHkmqQ{QP`wWWZELI2ph}OCMt>r=D=9Ffb)%Lnx7uH&-}sCy*|=r+`M6waT*)810q$n zT=bZy3DI9awS~6rPFyTsWgoQ3rwTh+ac|MbEx-Fg?-rS$BR>PoZ)yx%sy>=BF<{E` zReg9qNE9G~_7X=bkyJ5M^{M5tTjtgm9a`rHZ6A%(y41cjSgxyE!Cp{I&nK6f(y%?0 z3KUf@K7?4vbPdW9{1CNBgraxYI47CQGUVvl#+H)tOBUr?4pjA3#5OQlWRpr$mVYHuE znh_1j={y%?ccqm`OK|?N*`Owsx?91}SzJ@FJxN!PTtq?jt(hh+U8YHn2 zU$>4r0tb}G>2-fa<+_ftWtp;-KnK6ge$M5lrug7g!gfsM#$) zV4#H=1Wg(81>YGd!3K2QC~p(S-04!|W^+z>2HC~#o*gCV)8mTpD45Hn$&hyoN(=ox zPE|5-eox3?FB3i(OHCW6&7ZO+Fmx;H#LHGGy$oGAabHoG8w(87tlF z)A}@!hrC6gQ9EjN%+syYzvp?jQtfr%dzQV!<)=5X?vhuyqb=(pReIeoWoBy#3!4Oy z!BYBG_EFaJ+dWt0=3LV_3T?dbSnuZ8NlRS6XBR4TruRme!d?Wxy|?t0`g1t>e3KNY z>qzg@S$kK8XrSs!N8gu3dNCh7BG zIWP;J{6zP=p4amUmv#bH%4bTd?MD}s z89;;ZLJH=jgh!`ZXqVjM7d1{HO4He0=OMlrC|&0fQQ4VYOe&j@TAt~@+9nztI2s;= zVrkQwYH>m}?-7m_FL-R}aC>ulsjOpP;=b(+ErwG~9op%U=|SdS@c53b=ymB3S3G?y z@?Eyiq2>xhZ4PFeTrd~ryVAv-g}_F)3xuO4bph|LsrjhLBj71$smyxo@y5PwHAiOEc8#^xaza+V&AH zv+64<^KNq0knkJke_Sc0C2Z4=I0fon!@h2Fe}BXE;fv21S>|+}P7w5k8LR0XY-^0? z>A5zq(8z>SxmkSwRtJH9_a-a=DSNxML!%9WPB*EPU2!6xca=jGFX6Bs_U zTl8cns$2?1N7z(ai2kY9cJ$I9QvPl?Pz9-$T2W?yNttw3_hcp~HfTFTIT~8w?-qW~ zB}T znV;k5O1Sm-rUYBaV6xxqZJ%SmHZYNn^YaawN1gZph;1A-zezyqDUuV5 z*ess9v|p7^PKsoke^V_z4c$^E0*c{;qN*1OX2X;PmkQZqVbDo$PcMT#);JCrhZ_V2 zPo><;@)9+ z2OtQ3SYfQLJNV15V%3Wj_7SzWl-zP0`2iD@&)l>b=Us9OFub39QjR?t++~u%N_{w5 za}e}fu*B_2Pv=`{ohR<`#fyQ5hry;H9JFgchn=j*w~X;TAw{wlKn=S&O23XSIR_@p zhGZv~#OZB9`g zei`!E?i%LfdIM`3jBy}je1FsMR=4WvEzu1;NO{2SYN(oj zp0nDb*YiB_$|E*fWfOjzW8B0b6dPfW8`Xo_hA!OPjZ(Bn4sST&TwttEton&K`qlcP zqg4}`CFkw-ZyrHR?iiotZT!~ApTRDsO;$j4vA<+0DBJqI{;n+~8OUm_U%*ys zu(3BF%N$8#(3j|e&vEY~aFgw{M zIP;5FXbTQ7M}(ld!r~TyfMinQ5XX))8uouNo?fgc@@dhE!u>XG`Z2RbY83YKAz-qY z`>m89mZp?8+^;b5(kESsJS+6ovL!=szQkYs{Y`(9RYN4C#)_G3jotIRh*$}lVNv~H z@g8Gr{7RGS=PR!D9nlH&FS{^3G>?v-5akYkzTi97FChn78#E84p10n+8(D3`Zzoq7 z?BR@2z^}p^fABu0Di4epp^gQ+=2POYBW~fI6tRu|-Xpe}iP=?_WPn4GBA9p*>Mwab zTLBW;Svh~5)OvMj*&n~(@nF$|$Y86VY%6BGzI&NQD(7HmAr$wnoG=%N9a*nsdWJT_ zv&iZuq-**JseU|}UYXa-KXq>V_^pM4dM3#XXx~f#Aj9&-^_Tm2rint#+nBMUYK2EA z*;2XStVSE64t_$e>!%=AN%#nGQe$k*O)5Ltxe_4Z9(_IzBj^;eHgo{lQYqH&b1;;1 zOkoE8^7FLt``i7hj*e|cw{`Sxo^H2`SHfDP22KtqUl~X?abD}YWNZ=VauVAajrP;KA%+}UH$N11cjKrEnj%}Nq0 z1*(-iZ;Q!*#OgulL+~<5)3{6<$o6;-B|UU1ygPL69*)lxozltG3J;MPg>}9uBxr9N zsYVZ5V?PI$=)&uBohdrk`X3G-%k-f4$7o$=m3JfRq}1-E&SHJvVW_S8+0Y2+mm!`N zTZ-g^coiuu`7KxV+3K*b@RCs;(n~}x)O(J?g2ZZtRXAxD!Q)XnmpHXeeI<5LUNxWMDTdWC`IR@P-Q-4 z`IIL2;%RPtYn^oX&{1tFF-lLo0F4{U|6;3Bal9Ld2Y?gR);N*9RbCzrTTH~EXE zG}HgGnb-18Qw8RT7xg)B@y2_6c(;x-=Zei`b#=<3di=t*{@sF@pHXN^fpwa3zSBMQ zUkRn?ZipP9mhqwi@0cDn>66H&OwX3Ui}q7Lmi5E>XZ1EZ!37=jv)2bjgOB?AMjE^+ z=ldlH0hhl#C~WkJ^VFB2YOMyXy4hlm@FE3v69i3$=c2--Sm_4*GQ>ctg)2mX>h%db1(k5$_@r zCmI-vk#0hWO7a*fx?JW#ds?F!RwcW!W(knk?H4QcA0$#y)T!ZrcX8;Nl-g3)dHzUe zE#1wuPQ0~g8g<60H`Ski9tnnKB>bq-3SkDjlLB=>pE0WQo0cqs2Wt_w_G3K70rFt@ zhXSPPOFJMV1Kp zKzmLt9hhl;XbrK6t&Ey*G9{qH`dFY0g*^C47h~m4k8YFcd?QS*8;lR*Z~NTot&|%y z$9LOG9i$!-@u4fP)lH2(kyklzA;wkrXX}f2?T}*e)ha8!p6M^44W<=e!;H5IF)Deu zy`F|j{e@>-833Ly2oxMcghDNY0^z8lL}R);qHXDEm=X#$yQxDgyB~V#mohyz@ZLA) zUUjQ5zuZTHP?CcjPWf&={sYIKc~N~NQ68Gx<_rAlpK%30hz=kt7aqjTkk+*zNjHDP z4Z$(56HmbYzO&_i?H9HiLsg1Y*z^cjtB7ir`GExs z+0fSCL84zOOyv)h;ok@D+i6zT>ceoi6vp@5Nr7no5YIpUDz;eIb?gZosA@SF*Wb{; z@JE_GXBUi-sG#ABV|GX#e@oqp!RrTzrt|rK(>F&cuvE5Jn;v$(Bfn|hN!#?&9uxaN z%J%vnWgBSZ(*EoMyN+8h&K~BmGio`RBTX(;vd%3lty4yov3Cpl4}>I^Ns2>EUJd0! zeXM$8qxvIen5J1^EmO(sJa+&}cGdkdJ;l@6$xsgrZwHxWgwEi046a0g;eZ3$mFaoO zUjWljbeCHC2Fx^^;;*=VU_F(x+^t8dkK&yYw;L1lLz0sGuS0-WD^!2p{(o}__FUsR zMOo)=b*uYqEr*Ea+aX=5{td^z!XFSrfaoJSo3kV7DgxG6HRz#gNZ3GdJk1GgM77q_;9EAwS8dJ`r=5_L2VbZsBT^a-sjj6dSAFz?(SR46 zLI2|gyE#lB3i@sUn?Fdm8CG0~lniiT1r|`W08I|8f8-mB2=Y=f%`@s^ZH@D6NT1B9 zGA%*`TD>#k=}8adPF1w2`u){vo(HW?B~S=GUA0sT&JX#c*`}G@*_43);Xpo!qxoad zd%%CP4lrzQgq8iEwfkvGDzOR7gtPtmPcY3W$&%ETR~xlm>$D65Je&yCeiaYJw#qlH z#B00ZE}xp3>>;!K>1F=GLlt?zfIzZv?>8h6D2GKj{X1?>(%lTDCaZOG=-RO;h&||X z(09GJkZ7ra2=MvuAy9|HRH{+(J8_=*&?Xn(DDW$Q*&KdfZ&npp)K!-m<=9Hg=}6bU z?`?<;jc&`p0pod}4sccx1-~D>(cc@l01UZ#v3+U9Yb|^SNSGcDQQH`(L1b&PZK(6% zG1?)_J+Q7ON|r^05vqB_uVGmGhXWi$Pq$1(R%_D;?!|O(ODCQDZpq^Phi*^asRS^E z1h1S2^k%7YPVX(}Rtj!*N9lTIw=eb5dkTr32Y(zcck}!odE)@iN~7L{q5LUp0+e&m9vw1Zp6o2v)%w1X$QpBTdDV_Wv%JvsQ2GiX_VVyQU8*`Kn zTko%u$SCl<_Np&4^7Z0UYTr)nVrmFU@Q}+I*9iUpM>&90C`s*OttQJvWgN;?H63p@|KbN z3f11tc?RZ6AL{rf27N8qgdA2j?92uEx?v>3Yw2Vlt>Gf2Ekm6!IY{~+fc@Y}YI z)3?}+!Pu_>li0o1o_x+K1sJ9km8BbgOKXqX?b-G3+WnK`^vZoZAZ7_uE`k}iJ%t`U zM|77V4Lk}3? zA$93_6526hM4i8*+|__m@rIOu{=ri^U_qj-4(QHb8|Oj&S0*yJ3fjNkHA*k-<^Lgn zACQV`rN&VMnK4@r$V$Ixbaa_2H)>}~xO}Rj&fdoQA(vo5^++AcdkAu$$8uzG92yip zbCU#yE-3X10eTUhQPPNtGk6ZGp@nxA6wkAuV3E?YPkN{^LzDGhevB8QA7^luOIQDfC%M^-nS?Tn!JzoEeDJD~PX42> z)*Z_cW?qb%iWFvat1x@tO8g0lEusW-MH&B}(2!5^pA4f{f5|O2$G!db7XNMbrh20c zM&=ce-8`$=Z=(PA5J4VE=9C;_091>#j~^n^R4w`&$8-uCXqI zARg?JZ+X+thSGrv5D$dGxcSDLd>}miD#!vABd9+pQYeHD8vG(9}GHd zdW8@FwIp8Jw;<>;dk=G@%mBNBWUT0pViOm0{FSPJO)CE8=dE#O_?9d$C(HiS%ML2Ua)?IBkq)r^{U z9mZF+kU|5G|9)n(F7k0pv%c>OH^&1ZZ6&Sm*}Ot@?NocDKJc)?95(KLJIIw)Q$g{1z_i=iR=q##`{hO zv{+ut1Im4Eu#(CL;zcDtBUn2$V;64Y1;eR$7TV>wrUBDzUS=f;sRhZCZuLu-Kth-B zMHxL&<~hz+f%}(5!4Eik%-sR+^gIp0rV>#qscFHN_cpn`#8eIEyD&$@mMQmt9Ssef z^Qrne;iT#K6t?iY0zrc9k&m)(Vh&}|Y7U1XJP28>xvb*?dH(ZT%69dH>jYUMMPkEs zFhqngaM*TGq@RharQr^($({e!rRR|Me{uHL0ab3>{y0qcqH___T~bO4BHfL2cefy2 zBA_$~(%m54rP9(NNQbnjgo40tE_Cm+&%O7&_kQ1hVLi`$MvpnhXUr+5`=w@%FW=gi zMYh;atA#X|{lk6d2+Ys$t;E>*L!R44uV?Z|-{SdaYH}59Qitrt9-1|TIg(U)$AW-u zRi8t1$bHbfwm!Qk_om}!tFMy8n0Qe0YUPc-gb;-{{yQ_#wV5GG7?WDjpsEEYUUI-l`z`KQoq7MG86@~lrZTAzag;9SiU<$}C+FZ;yuPdN^xZpU>3HZ+)*9X>yHj)1tNg^-Wvf*$EzpyDp?_-%SkRp8 ziJL9#oj^^u2ZxC{T&)kZ@2nLiGo>!M%Gb^-rzIBxHxEkw^Z=Rn$zaXG9qK@6q?qsy z6AonmoYa$Sp}XQTD@Gw)dHEyj!_zO1ZqC<3f7VsmcuLo%CB}T2s*#3goqD&APRg(8&=yK40lr4A^?~e&l7OBQt#TeLIci zcW9Qb@1JC>#1Nctk&IVx=MS-$&vg~Yb}<2b5Luhck;Z%H_Q?mwL(PU-zc&`VdgF0k zWWz>%C*R|~c_Fyp@s!ECF?3Kml5FxoGOr!<`HX1b%w$)KlUVcqvWC_@*PC|n8m@Xa zIlb4ASzUyg7?E{e8U>m56bm)qYo3IXDxy26z&zC^71kM^YA}nPPZZeuAPM4sx-s5>Xu*;JdclazApjTTV zD<$93!h07okRb4g=;%U zki-77oalvM%z@5S@qXm;UnD~LPj*J%VZDjr4n(-r^ThvP=2!m9mB7nH5i~PzMC(lH^IXG?&e);C)O%P;`-1scV^y8Lz zHe%%UM5YRqZ>Rhu`zXeQlmY>vIWfkR&$Np1*lc|^<;h4#Q{`0Sbo>jllfZYO(U0Ik z;oCHm)SMKQLR7S!0+IS-{_Y-@jWxmJz8nK zKS}dQ=xxsFoeFZPjeSIOk)5u4R$65XU3Mp3 z23|*Cv7keFvJ3|#0 z0;9QV-h81m=w^$O`?gZ4@3)JKc)(Vl$VeqIc50b^W~4{LQTds6P3>{7(B1dk2z1e= zscf%5y^c_9hrWpZ%#Fu`Nw(@g!4JW`!-7bxnHDk|j)@+fB$`PILBYid+WuaWJzUnj zdg=VpJ=Rn$DLz6~;;sG@QMDSRDhXQ7eASozm@wx9tI78qMR_RCHhp<+s5bkgdnKGq zURJ~Du>7(H-|pR~a6;mGlW;si?5EATPSr#_OdhC`elJ6w^%6ji}f8QQf%poX=aN zmGv%=gMo-_bDy@>Af7TTS~;70L$Z>4!)=c(C?7dxv2H;v{#dseuv*3yIxg zq35UJofq7}ESTF%KRHNM=dax`fr3h6`B@QXEf213nB^5K7lluSwAKhR6N|#fY7xvv z1rK@D`kJA~#^3!_bR!W1XV01HwxXdgv^-Tu;UinQH_7xyrB6PYTfuPY#CtN>@&}!m zu?A2k2Z_+F2eBlES4Qml&pp6IrrtTyLQtTg2;=5yk@IJR(4?H69hEct>rP$z#q-m8 zmi3v=sZp-T&*^#Q#bE00 z<{GGf_>|l224PAbfUwk^`Ed;jJVbYIc#2I6gYo$)9`y*J+dJd)6;u%(oV;86KIkLz z@yZQe#d%?foJv7wa?l(>Ay;VV?O_?cjqdr$;~V%MctsyY;`5cxARO(|K^B8PY{<>h z<(mge*KIzR$g}ECTTlb>e;~dy)yaL-)u1c(HNA_?e;eqWTCY&;ix8C94|=`Z7#4v@ z*`*6@=WFjGUnZ6YNS?q8q`Hettj@%Kq+1(Y)RG&A!$>+6FDH10=v7p+wP7I)j~q_DJ}deIu1;HL zKHHQ_Zq=i``i7pM`BlIvoLeQU-kFnhYzyF5;w`^uAf)PH-&_n0exd4nDl^rr%|7~4 z057WqM@*vrZbwpQe$>QLx8NZ4sSS6K4;&x3tII%p1_;yo;T$RPyJ2EJ(k9!RURpcV z&w~x2T*lkx{FyIIn{(G{J*Jo1)WwJU<4sqZBJt$~N4S_6#UZ=bSy%VR{>+p6@`0yk$~DsN@I6S=aWlF0qu9^i zy$NbB4D&R*EeX_t08T)o0dK9Y{LbHXzpp=B+78>9g%3%jV6vU9{X~u_H2L@DQQTpc zJAEv}tBQ3!q>FWYF0qDrGHdLIU_?_nCUgD}wXS$u@ibg-s$)Y3s`pxut1vs) zEV^Yf(opTPu*Z9QMO_4(Kd$w#G=JN5-=vs3O=#oAO_FcbRYj+ttE*Da>xk*FwbnCJ zyWQ=(G;tWdr78AtsiHRHLe}+smr4!XO0)hiI$JIRpOhtgWGaA@a?wg#0&S_tY)dAs ztJ14vpeen^QG!HW(q(aZ?i?=(k*^Z1256FtD!%Snz-!MRy~pmDFoF9DXVb|_nz6JI zvQlyOtgtuF=VwU7v<2^_(#;-Z!&J@B3S`0wUrB0KqH%7Ty4(*tmsbworG9_ucgL9G z=ELT&H1`iwJpNXRB#EmrA025CzzITTo!pxgVs7q8g#hXnQq> z1o@dn2+ibI8adiwOH^;2iiO3RzhIc(^V5IoHLrdiKKUlX{=EJ(?}x=-+89MJv9m4O z`w}b|`tL6Lj2)a4b~3a#{)#5qJrCd%>pk(f?*aFf#_%z`F_rR(gXg@mQFagGQ%uod z(cmu#g^k&-x?ItCigVEj=cxbH9~glztup;uh}Eq4O5#g}%;1%w7kg{y-BN9xL{{og zkC#W~tzOmHXG%&#pFe-xo_EZ(4UOeff2GM=`ne!;J-)E|+pEMABhE^n^tQ{!(6PC& zLnqjt9l(U88$l$cKA5@QQqaJ7Io{gBMdC+cfY+1uCX^ zi_6%GF3qSCeMlil%|Q(1s_4C-Yr*h=oYth+}E9L`S#hCz>xio6X)w=hL(Rc zqB*#!X9CCL_HFBpIFecSb=7C|n8-(movdCd3I5UviLlcuK5kMdq=UR#t?QEB{HV2! z^JZU!`e!}udO1Mg)uaeomF~AKe`sFyv**?X7gC7*7ME96@O zD&+D!INN~+sL4cU-`c5K- zT^fV%x-q6+toa51!+llX zHZwrz-lRdVPLydjMOtT0(?Y1I=~{-TkeyEzBRAY#IjUk%lwxKNR7A{F^mnRuT(evC zH3u2=m2{20eRLD5Tv`-vVx+}POFc_wj@ z>eUNP)!IGiAm!uYkx09K$g+38P^FmmRpM;yiq0R|#(zkkHpbwQ=tJOH4q+p;4dNX* z{`AzDyBzQNXJt#}(857Q=NO2x9{-azq$%}1t6Cvge|cB^AnV!KbcHO$AiVKLJ(LE& zm*=(@d91W%oba4l3qML2Ox6CLPix62&j^JCEIl{>jAQRy{~3`NG0-l6?MW3ZNDZB( zFNb-Z%7*TKT>Elyux_5vEk9(5fkoS`6S+ngV!IsOWZqHV3$+c(MM*n>>%*?`wBXd% zm4Pe){IR%C?f_7sWH@`32la7@cJRF6h%EdTs~sr3zi!{K*S4#x$NOw>QP%`wZx=^^B;^B+bd(;m+BoWAF{m}@Qg(-&#w z@KOo;DZyE5+HpVidCJc}dQ>C3Hij$ykG5`3LjW=aT->)lzw*&y^cdSbV=SOuIRgYa6D! zm=f`)4cFs+EY2-)h1IaDbOpwVw%;(ry6bXzip7dfm_@z5UwKL;KxgWAlU*5n5a_l3 z-Dkf2pa~MX%Wn1n%0CVL(uaRlZNKY}SBXxV2wi#jduZJH7+^!tIcqBKm)J>%!3r-oKg} zhnP|6Ll%i{=R6L;IC&V}zxA$aO$GU~alE2E>*2a|CyI>K01S;>Xj1iHH&w?r4V*Dk zdY$2Q#ppJkI#3%Up!mUK!0goU1+}FLn8{f-QqN~H?4t=ib`j2iwx*#?G2U$tA1jKfXKQaVhQEN2O ze;8pJ@{nvO4n^Or1Srir@5oBd)>ii;yRj5bdHgcX*+CkKY}>i{!(7K|DwFAJ7;w+G?#5yh;N1uxRM4l zt3Finy_zyX{JRMQ^KNHBpqX0ZDqY>@C3U-fStGn=)_?c5Mv-_C!;9!QA_G(xOjdo% z(_oHmJU&88=4CcvKbCfnIH#a@YiEZLFVnYVu=|IB0W-Dkk1+hPL>8DOI{xpL$Pa+% z@cNs;BfvVt+6iHQp$@j2a+W^HB2sY|Puk;;yGxfk(+69_2YZ`#gRJ%erZXtH{;taPFm0XPkBU@r<`Y>J*6J_*^yW*lufw;_r#r|wkkYVQl!@uzTKWfN^8dG%k~Cdc zSIqN~nO44VYWm{+Z%t6ATM(Kr=uiD85E@XKVDtIgATkQIwc(V;eW&2HTch32nD0#n zQ$$0;Zvf8x|9~3&hDc_{ZX-cym*H!XHQ z)*ei$W&dfyI=uo-SS^mU1vGz*VIa+RTAF5KlbLXTR4efrmDMeB z+o_-FkB8JR0v=Kevq<1!_Mbc@M|#cpeSH#s%AmTtDaguA!QnC>c$o%a>9PF@UI>2& zuXmMtga8-BIe$LIc-!I;p8SJXbs~e|CWw*#Gs-Rr2ERbwvzAhW+G%`&rmtq5-?v^909*!aFs>dK08}yONi_sBbwATSLZjuA+ zyyW4SUrp5{Sk1`!<(HIY!o0F=aBo-H)mF#9DN)HNhEWU&HlHy~WNI|=s-JBjcQVM& zawOsE1!3hu`8M?Z*17q{rq(lrH=A4g-_{J}bB%>1i-!Fc%(wEhpM5SGXG*MK}0Ho7q`egY$)Q(|f@x;=R9$~c0Y|A2naQ&|>J zAOr!juw$MY1vCk-wGO$yg#QCY zRwwRO5ZtAs?5aCX`V@B)Z@($Iovxw3}BIeR&n`#xJ zz=QMYw=nYk?86gKprmvdZg z7x;wh-xBdWyt9;(nX80u!7_)UeV#6x2zESVv9_pRmYPvXLre|a2T%D;KP>7S`oV{< zjZ9y-Sr_V;->S$NRIkJ z?$b(d*n<0-n^?$HgQ*O6%SPVd2kMgwsO9%>0)85aQ+;I7IjvJ~L&SnoF)87SArV$SjsfE?h+?Dy&7)ASwZ|(cgzk?ap(q`AJI60Rr7V;>c+3eko3lMwHJy78)@@_XBB1 zMN(+hysU+zL1V4^DUl~1JyjLGZ=O6SEwgF6;(+x>qyi_z4M~JOrciK1R#J$QbSpUL z%B3AiA~fK`&nK#CeO!xn7e!&kb2)1aSRL2A)VaT~R`6<9=3~2;Bik@Zd`ola|FG@_&C;p0xsVU-m&77U0ih9i6%2PiAWa|^Qqf=pAPP)Uet4Q}sC$K}NJxtiR;r$&B#zNY zNj4sFq)>#^q0V4q6S0XK8nIx1xa?eRao_xFmr7Fa8P|6TzSoR)mp;_F(+`Fg z)P*(9`UhRM%e$K%O-8XcghnWd+nqfXCvUX|T7NYKL! z5goc*iZu7-BUtMfkJi+QJ}p=bu#)uCsS3@F-YvIy7fC|9Y$`Dv>-t`AKs)gR^BiJd#)9#HE2vYp~uJ$EtJ4 zfP<;b=J1_ZcH+k9&>KA2%)Y5PZnJ43a2DC7hZ~|w&j=J5qS9c7bt8+7ruZ^qjNB!T z&|9diYxbxNI-)Cb&~`$FJOzf#S|J4ABaV-~v7A$1sKtw~s{%GXO7^y@A9;?({r&(Z zL8Y|e3okUaJ}Bt=b8mfmU0)>8hi0{NaLseDf$ebTnOFuwyL0zi=N$pRn{MIjy1b$+ zde8HSh*utcq|rAdRxw1cMyuLUA^E5^pTEO>x*zwL)Mf}N;o2YL4hb31f_*!OHA|_xXT<^^HoYASl1;=R8WTJR)sPw z6+X-9R`FFEdV?+-yB(@qohS)5g>USf)a5sFOp&Jc-b<1eFbGTe2yi$J8FzbnIg)lT z3@$(59==fuW@rv-@LD{bU67dL4XgEWsmOM)N}an7MG+lol)~s_x)-n#ZtD1uUg(KH z7*Q0rnk7G}?sK%Ek>olD1ab!L=)%B)-JUGvG~8%GW9^YT!_@^7w71%xpZn!=@2BFwMM}R z39*$!Z%wbi))PKP^}iF%Bp}9@0uH`NlZd>`p+4?3Jg{UVvh|+1B#QD~yYbD#z{i_! zr+F-Zz(RU@;2op)NFMa7?%vyPRT}3G@r*hxnmO&SyY9@Neu>Sz(%0u3$Xq2e7gc;~g2h<&Q}@-=ypbIjCLAiMUc<+B{q0+Qa2mm^l0+a@`-E$Vp5QF2cgzu$9t z*CS3(Tl1vvjRTT;w{EqJXf%+J3EQ@nVG{;)xjRw3!`9RDm(h6pv4ihS_@+ZuLau|O z1^Pbwz2Ffug3e%#@4~U%{kCm$b;4OpZ{J6<>`R28kXn_u`Obte?=U!&#^Uf1C9eg` z`-&J#;h=0YmYLv5#8X-*BU;QO6`WwR-5|}RX(#K$R^8o-Fl@wtni#Ifi4`Z*VfqMU zwtGB$f|zA;DW=8VuX#jh#aY1^_t7D1no9i1^p{$n@!qmbggzw56_r&!YC6WkvB$#3 zPgdUs=K$^++wmGa*;C)?DQO^}kYvYCQs55xvGJC~{c;p{j10xs+%>7o@_r%{Fou00GJ?{UQ?1RaEo;RW+C)0$O0*|-D$elo+uM8CPyzVT z38R}!C3r>Snr@LuM$Aw3OK|@C!hWDRi8e?Yn8Bn5TyNj{XUHUUqdS2MQ zsfml(#0t{!m4^Ecv(3(TZv7c?4GBu$b}4;Z?i$zIkM^0a3j=WsnQpN;It7HV==*VF zrJKH5R}Q{IA^5XUEK~b@3g-)tsxqC#-szikKgm9KW#i)Z-plFdu{iKssuG9}H_0dN zX@|zTb7SgXCa@3&Y#;RXOq!T{&oL#4gNjx;)~D#8c|CpzR4eNg!mqQKv$jo7*8QS2 zrDI3yj$-$!XMnMvLUieAVOEM}%Pn_02((p-+mGmz$?rs9LQlB$xteY!_gCcog4Hhq z;!fNTca|m}C2vdgNmFaB*vwJU>^vp|Zj;%5G3KQ4)@`16Z$j@8?`V3v)xBX04r@S> z#C(2&74{2>C#Lu|J9*Di=lyxupA9!Q&ZCN1Rxj6bv z>^NXz5}hM~^9-A+Gz;7S4|6HpwXtnBlzb?hyxbk)Z;=7LVUMr&zLco6vltxz)s*s4_N`+6Mu4j7Oy?UVm zfmS)IoY$6BjQ*%AjLd`{hC592ygEe#=cgx-6HM|aL6TtPipHQz=u;r|`;J%EEB?z} z91G(;-Ci*9A{+BoTi5p-;(;?wQJN+of{~Gc0$vYa!DxyGQotdjminBqqAb?gmC9Il z#+PfgU+do@B)}Qpkk9Gcqxuh5&FIag;+QA|gf*F|4}fPi`Y-uMykhysHRHxBoWE-w zb9ppk0#N`DSYcZq%s~kA=pp`&pTb{)U(?O;7tbKiTDJOLIp{U`Q=@QK@bBn5%kiL1 zB~Y1*Bu%aElk=mht_l_#XRoh1J|*R|DY+?i#TVkb*9`dOAJmZFu@@~q5!ch50;6Z9 zNlk?U#;WZGR}v#|1We!KRJ5@o)CP%Zg0PO}lhtICsRT5y)47{~Dk)qM?GyVt6rYET zT{X4aLN?<$O)vH)xEBF7diGAD(QvmbicyXg++zh-JFAEu@dM0EF!vQJUS^GHfew;4 zm-)qRXFqh%`Zd|+7nQvC@wAS`J34~@jsJ3cC$-E~&zCv-*7C6rn(FSAODZ)}Cb=C> zT&w=9)*F2_AUU?nj`;Wk(6BVFUw>-V`8-P`R7um8oDaC~(^!F=Sap~+)KtZ`9pi&> z5Pi87tDV(Ggs~#)Q!BoLXOfSW#(+dPCv4@CKJ=z`*<HWPS4-`k z-9H~3J6+gD`S9dk!(n*HUp)>GQkiB-X!;b}4L-c!p7HYv{_&*5aT_Ffi^;@$F4ogc zkMvL>}$}3P9u*M{ZjggsTz3atrg@)eE|Yp zcyycG53Qd`bF|XxVmBADMBCzzq~VZ8VXX=HSkAXn`w1t#y4`V7@?uIwy$RbE=~;fELY4SVA zem|?7h+*X6*y)yNhE?z2&Ed_Q2z=0Yk$11ZJHvb`(_j|Gr{cY1iBKx5{eVj@(edf~ zR2rXfq(7hZEttM}EJSqmt-y?XTm~kMU9~Y^X>z!JRzMB2-fWTKPfVz^sBvn^y{*8H z2%VjQqwXXr3v<>gU2o7=)n99gsXniZ;`gvXJ$=QR@(h>n#54^;ujiLjO3kbrUvlk= zK*A@vWs;McV@ek{nV%)$>Y`&51q-5m3(c4>CHfAYr~p%7?a~hfbSz|>aM85yi52vY z{LH8AXfN+5NbJa^ftnye+Wqq=W8R}dSIgf~2D0EkYUtBbe5kNr@VygFU?>k2@d^p1 zu`<#b-`$g8j3WQY_~|h+r0Vo4ZNC8tZUt-}^(S6ieO9@#47i$DXYnqbgPwQ=4{&Ml zGcv|)>53~0>)D?N5%C4R{kr9iMrVOv)UxQ-IA3WW zeJgf@N`WRyIsjT(mUMA@12%IPss<`yYAAjn5nqUvP#7a|L?tvRZd@n2cF0YD~b4JHC z1m%aFYh<4T_c)(tERnVXONU=o0``NGLsBe@M@TX3`4f!PGqDp@uU{YnpG?{)u*zPZ zvo_s>wC$@P^+70*t#xvL9ew27{_;IZnm@WQjfaR<#elZgsqoX5{ z^hbh_8kLhJ{DxBk?$Of+liVTQmnC(E)vFBNeZfT`B4EzJSx51;VzLlNoJP9|Y;D!g zjMT{TqPrL+*@iGrI{ithEhN&~r|yIlC7SZJX;qVf#qwAEi3*a2>pkUDuU88TEKH(T z=}aI>myC{-!R?5j!1(LZk!4dyGWY!6{T{x#z;W&=V~(R^pH%CXuYwK}DINoFH&}bg z@Zjk%pIV#K#UbP$ek*}_CRS0ZYf+bF?h5~%rNe!sbGc?l2d|eqqgcS(8$0b0HD8pp}2X0kG-FWTz-bx+s4Y+7A(H;mrWqW>J z`k;OxsjGX_HX+7PWdI2eKJi?iljpvg-2>_;x-;W~f*{Qo%}re)5_dH)NhhbZAKkr#cJe|(RNvl&vh<_wfdmXQg1C!iV_@^E>5JUoM`r|Z zu{$E{ZOONN@lyO+IKK*xILO#ICU`9OF~P7y?E2P$USJ-T=FJ0T&U&B3eK`5y6LeeAqgZdT5nt4oj`Y7}|@S6EA&@11q}AHf)FOi)O9+k7KjRiRgKqdcwXP zHX|~BhzFDknyP*n2(hgKEB4HMm@H#+YkUu5=j+jCo-oVFnbzV<(^qjhJp_uPl~y{3 z2$tNz*Hxk7Bd2*%-7fhm<@)D210TO|kLCHU5^ROaKE>SUX1x=ShtbQ}V>j7`RC}=b zeSXE(qcSUKB2n}+0pz8qqB}Shf3V7^3iOufXiY3i`|%Ql*%M_$X%c#QKzA2yAX2wxs zvgnKN!!>B!9Zk;3Z6qZ_?)8#_S$KGlv?rL5*KRsIbkb!6#aZYU^{}Zjk>N5q}v%3wBRGQM+_Ly`vJJaEG#*giR!7Yu7i3 z^zZ?6W6DFR=*Yw8q%dul_sIlcg4x^xspT3)+3|6N^lK7-w6-yXWZtyp&(y^39gpHg zlOJVi>r7nz>cqSg$cW~cf~BC;$O?^lirIK{_GSQ%>I#Q80ee&n34*($#kE%!N>S8; z&o>=Uea{&*w(;<|-?%)X`3?%r4zpikVXLf?RA$Y1nYXZw&kJhdx_2P)UeHZynUCRJ z7TpQ>fxb?o!quO8@S&>5n=0>{>csqmsWRtZxNxR}@u;e-Ix0UFqKA*8V3JS6u2;eY zKo433>6Av1y^dak#P|A5ctUi%XCYc=CqhpS}uG(DD)H2x*ObL#Cqev^sQc~)qdIj*Qv~NLD?^3 zb0VhvrPWd>b>1~geWALjHUoGcXEh!Deq5-dP{Y_|G5Pi9J%EpZsj%L6@|3~Z&9AJW zn~VezAw)^X6v|vo_aNo)Iw%NjF-ou<5TSHFUkl>0`ROm1`=k>+5$Ce|)0x-0b9@h) z*L)BTPIsUS(seM(Np6OOUWl+5Y7k7hg6o%v@BLA(LS(-p8(l{I#Qt(>b^?69V^va{ zD)+)k|6nTNu7qbTM(MU_4=>!F7MD6aMJ0ZAvgPwBElOSD$3q#F7oWutZ;gRD_X`cp zU*B9u_TRqw+(U3Z$~_7m99&qGePn3w-)$qcFH|L}QtU7uCeZGF+|F-H@MBeSU%rY` z)L{T#-Qny+df&XPs&>x@?vgK#Y{kcdbykNH@5!tj#{Ro~)k#`sfb{@+tAKf?I8me6 z$oNu60%jVkx!mIh9}Q5>Q{r;04x-`$!X!i?7o{EF^}2h0eiF-b55R&q7!UI6zvOnt zGW~rlm(rt{EZL&DmNnQBtm{tw@pKM>`!=8E4u2ntlp|0MISK59+jAG)@Q@ss*co-( zWl&7C%0Rve90W_mAgw|#5xPhZYeO_Ix^AK^ zt_VTTJ%wRMT!7xQL?{=#`JB6ZL!;x~g(@w^Q&nGfsMQT>mewghGiwO zQ)`Sw=2Qo!KwlN6+_S$TE#L4zX~%#$8bq9M(`~&#cQfPNYC~;`9IN>L#O5m%+r81LTFrB4Ry?)^u)zWX#xeluX0u_sVl4V_dF zJj;oFUk=(4vTxr1?yuV7o1Z+w=W9+5hILlkC}m#MTvg_~8aMU*K6V73??*3>muR*2 z2Id!n)6O@Zgg=Jx9i7!*bU1d1vT#XA(o_Fw)TO^A6^%!NI9bB5IRAt6kRY8kF@|GR z>FgOIT7wdn`^?A53=7Kz6n=}oe(GRLDJu>RP~J@e$7VzUE`i$uhPq+cq@@>hGV|B7 z6V26&e}G8wAdnkh z)kcB!*N(g>1bfe#UcC2T!v1}35V(c~b9msidk*D89b?nU5x?i%ncV#m*oP@%}sAYSlATh+kdwUT;P7llb z04txW_vK^gz2(nCXOJIqVu&P+8RKuwUp0)|Dy^=XIXV-@t8m)jweYh@sdte~Y8>@XU9zWeXyhp}+J`^oev4h&VJ6;U}lwz(kMntJNcjcc>QCrYxEjru&}%(EWn8y#CGNUQ`b{>Z02>5;W7u ziaK(jwIci`J2=HS`wIo@sh84R8w!Xa*7xc<@^w1@_->i#x zg4ePcLLBc0z7GbeWgy9CO33M{%!hs0r^EYhAj0B~qb;iuOPY)zFxa>}uT3R;zi0S@ zbAGqf&X0-khk@%&agzD@iaHa&^nn1~w|-;}+H>GEVDpFyoWCty<}VKhawr;Vbm(gY zs8fV_vcaH6mzH2DynDyb$?Gwe{-dr!WxJSpN9oO%n0k+n?t%$sFv*@*HSO>m7WtR%gzeuiQN;Vp6TC<-=x%_8-kYNxuTi+o$m#~xld-pu_+xqD)oc(sc$1DquF&pw&| zcF`Oyz{q3xnmv>LxC;QAra%BtgW{lwj5XQP)F*pAQ0)x)&r_p<+rGmsPm5GvELoFN z&Jw}i#PHXfSR^DL8J2z|yiM9Z+6aOhH!NT2viyO$ri`QDvvaw@!4W&iJ(AFLeY}un z+E{sJ3$Cc$J)k-QZpn9KX9RPuK;w|;=^)DR5CO?24M9ECd|b3t{`WZ?9$oLbi+0D5UyW z|3F8>t&3*lbYbhtNaMwlGh5~iBk(B`Kr*{2NRW7O+i@(|%C_S!wa-9R_6fDlEkCQ7 zaC=TgcdOLDI6}YZMRR{YS6lr~)}GD8O6GhV&)m@Q#l1t*=)vxI^+0V8eq0WXHPa-~R#S8E@_771}Q0xHzwf%(8Nf^u45X zg0aA~eaNuz)_h+hw9*TB)u>yqN^kQFNj}u-Hm3=Vh?WASmm$QKTMzXLEefq_MNUYl zo4GyWJ-!eVhKP1}6CX%D>~j{Mg9qsY|KXs3;{7WYN`|0B23ZvJu;iFp1)bw=H4$`U zv^P+ndG{JP>n?+YqjAQjL17$MZW@*;09B$_h4S^mQcozK0Xr>#Q&0^g|5ijq+U5YJ z!x9#ujjy(O%WFyb-5ZZZ3qiorI5pIP1uUe0Mj2qMe~0#e*(%DbwFY$^*WR^Dg8m&! zumdCOfQ3AL#3gNd@P?oNn@-U|o~`<3dhn}Nt07ohPoLMStxgC%{f|-efBuMww6!hG zLtKwBM!T5K=57Nnwa8)%z|6AFeLKL+FgO^NNp2h$Jqcy>)*ewHB+=l!mn2j-OIQ%% znG8a!8k6%*5-QjcW-5}+>()s2kt?QXOC4&f1_z_alKwNF0FHqT@!yQ=)-l}eb1#(F zm$iP{E;s%CK;#Bg6n=murdb!fK2Ic$?T-h2bk;Ypx90t)mqLYLT8Z#~;YXL;F@jlFNbAQc`K**L`Q52? zPZV=0+WHw=D?sr?cJiMQ51_yPl^B7tI~w>f;BSl~+>>$J#Gpn;^n2|iME~Z-VVb%2 zf6|T&5BEIAoxGu#^+@vu!|Q91S!>e|7=vhT%N|e&aXuO9yecI@Uwy6>xbLwyuko#NpRvV^>|xduFu0&d&xz`srfBJa%IYqpR=k~JovNb%zd1#d2*fk>JY%3UT_|k zeA96b4MMKC#WjaZ7;#~g6+Ui(-7usMTqU+KpTyJ3FM)|MehMCil zO9r^SO~C7RS^bzLLLYQLQQGX}?q|XNbj9I!(FuJj3jVuy2W<;{<~~R1kcfqO*!EG< z@vfH!oE7VRflz}f^Sk{N!H)fS16-S*`s$?f1;f3H9q7LX`ml!Ei6{@a4;s{>!34AZJv z%O8IB@_87{m2&)4O3-U;)I%#1$c+APyRd8?1s;=J_*O_9?>R9(MKI?mx5>k56{H4d?rg_P!aGDaU6%E^nhz202q+CH5Z7wT}PoTCtkQfauI4VK+K8 zyd&-ECQn0ttSh<8xJEM)ZV;=K)7`dj6Cdh!z)^Ofp$3-B{ZC8&K;8}~!)QMgmr0%azY$G&HY<_^C($6~hrM27PX3L`Cu_VT?kB86t zH4mj7ID9p@PYASLPmmobghn3Eh*}=1&`KaqA<7EqBY=A$@m-A+K!&AuhqwFN;CDuk z4&#m-+2FY&9qjn-V|uV0}nV~Gw#m=Z-N1KVL+uw) z%dB67FGqA%k1K;vKdZ0^2Ga|VBPq(K9je!c(UqtV7)9l}VxDLS-HGp3WpG)9T9>C! zjibL@s2sYBgpQ`(pe8S66%OvXe7kp@(SW!pwADqcR)?Rq^fR>!DoupO4;m7E zYfIrC7!AV6EY$cVDcxsFZ66n|MhGoWbs3|?u0^xTc5U5zosLR2Yo55Wu;A}xBb5N# zT_`&XaMPg&k8lJ_eME+_K+ah`XG*71=;}+9{0qOn7r3MAM@V=g|XJ?x5(niX08Y9;ySNJ6P_lzbk_>A2MR%~&99&Fx~&E_thH z;UGa<(e~)!J7OYv0CFpa{YT@g!Uip{3g2?Xi=~HsGb#32C-o6+`wD^t=vW4T+gKFh zG=V#?pH`!FhM_~e7YR_^S>{&S9E>xksquHT!EZd+0&TA*6~sd#vdX$0s;1*{7EBZd zze4U1$x+efkfmN(@W@`@izGnm5!$ugY~Km_%1NdQv8fQRF=8`iQWc{W$C@=O2p`)(>+c{ zqV|^ZX(BcyPAP=Gq#z_n-&>`UWm4FBGR!LdMvM|x6-&qZhT4_Ch|u4rf**XfGV z{@T}XY2rZ?x>TwRpx=P1B7DjSd|kwHPaYGe*m<3c*(mt|=mvFmCh^91ivyDS#DfXm z+>-*oKEWPDl}M58?HzWEg8HI1;%e%EzfLEoZIYn-B!fkb-tFe{{E(lae`}=}bh0^* z=&v3wo1*|DrtqZDF}_&S;0DIRF7A*f zwA^i~kr(*iU8Y6Shxo{@sHU6zkdzYSvr0`wj4Gor?5KCbcllL(bB&Y zPJt1QNIh!o1zVC1lGbxy@|ysK1kPvfS!!qIUUXeMY%cJ4@35{OF1jX6yclb5J3Vm) ztVm<6YIw|P?U~IsSP!4T1VI(fq7{X-2UCs<9!yO$6x|<}t4PWP0g`t``@YDP$(q0c z8JNORqeo@1!*n2|iV7L6%Rb*o@@_I^;Uz-rxEjodOcTE%#6|xBd!<<6$GoaY{o}g_ zcl0&8Im$jOQMmCch{cPK!Cc809G)9z1|W0?bzP-eDkI;AWI2Rlw{!6Np^8YGiu zJd&i*=%#W{o0LUcL$$fzQ))TL$*poSVWLbL zCv?$;sbm$Y5Mt{*PoLBK@B6&J@Avn8zQ5n|e%|N(yl+EpiZYhrlufTCxu0dhLbKDV zwROw(8XX(1y(zip{R&|!o zu768Q>9R77AVHWVZs)>ewbcNYfg%CZN5U!hJD%e++Zf;FgLr8t>Sbg{fY()@6pT=m zXVrK{0GpSP;aOJ=YuPv0gF$`G{(HZ+Gi^W+801t{xmV{!`l_^e0thK{P2B<9k_Yk+ zHnrJU97aFWrVtjeiRJzsD{`NuN(8^(8ZwjoYD%4~ zD2Nnj+%tFA^ag6E>pEVJn+G#y8Dgp0x00%lT1sE*hM?0VC1$}Y?S+l5z#WZ7xCuWC zsH2X|1AJfjevZFYQ^-^qy?$K||DqjlbN)eKB1CN|UPw0N0%}MjFPFlxw&Z-5fJ5H6 z5bOFy)g86!)|q%?lmaqSv^tlHEMd0Vr2*LHc}is@A@l_w8<5eA@HLHk$~D=g9y^8XvH^? z#pTdlL@I0l!73Y$=t)YS`tidaldI1q-w{eWNS!Cl0I68y+0^JfsNAlb;qqhIZ`e#J zVG(i#vwm9LWf$^lbs(&(z&C_mO*)`S;(i`VV51^>pH`9_9paN*M%#ONNkk*}$Iw&9 zOiX8-Rp}rL&hAK>*SF8+A<`n|tffk~=@ehdsI^Py7l$@Wj)g}zXL~mv=Yvu{nd&U#D`y6>J@okvf zahFH4$hW*RJ&c+*m-L84J-Rc_HO0Zr)pgHd2dMXz7Ar^Y0B>J#jv3#c*&$Q zwHmq=8X-}GeMj}J!E*v>>h{eT&Z3kU$$?yRg zK5sx*mf49gqono!T&K1ebNw}7scQ}Qee@cRtvRGQG_d{&Q=`A5m7GE`_IeC8n|y0h z=d5}WT4qfGd*g+Y^#)!R8~Yy8CpYMm9vvaGDlde#7Ay^T=H~bX3g_VM=7v)t0c8xg zloeQV;y0ga#t7Ple0uQbuL_Rq1477LbhMI&OB7wh&Afn2YB8B#aS1e77g^ITnkgO? zf7%$U6YIWBTa0j{W2b`esO$B{e3W&LuBfTFQiySVzZ{O`RpHCY;wF%JFtMj#U|=J= zsL4MM+pf&IQQ%&_oL<+{vbCcuEq`_&i#_yZ_Gw!T-s0e&jd1g$Epa`p{KicrZTVClgB)B&>r{L!YwjJ2t6v>==(2pZvY;{mcY9v*h zN}9MhM;x^$aAo5ATf*^-r#bR7YPuh;R^ktMoN}-~d2*nYQe#z|$`m m{{s9K Date: Mon, 25 Aug 2025 10:53:18 +0300 Subject: [PATCH 08/10] Update README.md to reflect new project repository, enhance environment setup instructions, and include additional package installation details. --- README.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f21a90b65..a1219441e 100755 --- a/README.md +++ b/README.md @@ -19,23 +19,27 @@ We also provide training code, evaluation code, and model checkpoints to reprodu # Setup ## Clone Project ``` -git clone https://github.com/nadavsc/Diff-Mamba.git -cd Diff-Mamba +git clone https://github.com/maxmelichov/DiffMamba # This version us using mamba-ssm==2.2.4 +cd DiffMamba ``` ## Create Environment -To set up our environment, please run: +Use a virtual environment (recommended). Create and activate one, then upgrade pip: ``` -conda env create -f environment.yml -conda activate diffmamba +python3 -m venv .venv +# How to activate +source .venv/bin/activate +python -m pip install --upgrade pip ``` -Note: this should include all the necessary packages to run all the training and evaluation scripts. Nonetheless, make sure the additional requirements are satisfied: +If you already have an active virtual environment, you can skip these steps. Mamba Installation: ``` -pip install causal-conv1d==1.5.0 -pip install mamba-ssm==2.2.4 +pip install causal-conv1d==1.5.0.post8 +pip install flash-attn==2.7.4.post1 +# make sure you are in the right Directory (you should be in DiffMamba) +pip install . ``` ## Additional Requirements - Language Modeling From 2b105ec17ede091ce7a98c04a57cd9cf9f9c106e Mon Sep 17 00:00:00 2001 From: maxmelichov Date: Fri, 5 Sep 2025 21:57:48 +0300 Subject: [PATCH 09/10] Enhance DiffBlockPaper class by adding optional lambda_init parameter, improving cache management for mixers, and refining dimension inference logic. Update allocation_inference_cache to share a single cache object between mixers. --- mamba_ssm/modules/block.py | 68 ++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/mamba_ssm/modules/block.py b/mamba_ssm/modules/block.py index 1a7e06340..12ddc7ff1 100644 --- a/mamba_ssm/modules/block.py +++ b/mamba_ssm/modules/block.py @@ -116,6 +116,7 @@ def __init__( residual_in_fp32: bool = False, layer_idx: int = 0, use_postscale: bool = False, # optional extra scaling by (1 - lambda_init) + lambda_init: Optional[float] = None, device: Optional[torch.device] = None, dtype: Optional[torch.dtype] = None, ) -> None: @@ -167,20 +168,46 @@ def __exit__(self, exc_type, exc, tb): self.ip.key_value_memory_dict[self.idx] = self.orig def _run_mixers(self, x: Tensor, inference_params=None, **mixer_kwargs) -> Tuple[Tensor, Tensor]: + # No caching provided: straightforward parallel calls if inference_params is None: y1 = self.mixer1(x, inference_params=None, **mixer_kwargs) y2 = self.mixer2(x, inference_params=None, **mixer_kwargs) return y1, y2 + # Shared cache stored at key = self.layer_idx. Ensure it exists, update shared once via mixer1, + # then run mixer2 against a temporary cloned view to avoid a double persistent update. slot = inference_params.key_value_memory_dict.get(self.layer_idx, None) - if isinstance(slot, tuple) and len(slot) == 2: - c1, c2 = slot - with DiffBlockPaper._SwapCache(inference_params, self.layer_idx, c1): - y1 = self.mixer1(x, inference_params=inference_params, **mixer_kwargs) - with DiffBlockPaper._SwapCache(inference_params, self.layer_idx, c2): + if slot is None: + # Proactively allocate a shared cache so both mixers see the same initial states + try: + bs = x.shape[0] + max_seqlen = getattr(inference_params, "max_seqlen", None) + dtype = x.dtype + if max_seqlen is not None: + inference_params.key_value_memory_dict[self.layer_idx] = self.allocate_inference_cache(bs, max_seqlen, dtype=dtype) + slot = inference_params.key_value_memory_dict.get(self.layer_idx, None) + except Exception: + # Fallback: let mixer1 lazily allocate on its own + slot = None + + def _clone_slot(s): + if torch.is_tensor(s): + return s.clone() + if isinstance(s, (tuple, list)): + typ = type(s) + return typ(_clone_slot(t) for t in s) + if isinstance(s, dict): + return {k: _clone_slot(v) for k, v in s.items()} + return s + + # Clone original states BEFORE running mixer1 so both branches see the same pre-update states + tmp_view = _clone_slot(slot) if slot is not None else None + + y1 = self.mixer1(x, inference_params=inference_params, **mixer_kwargs) + if tmp_view is not None: + with DiffBlockPaper._SwapCache(inference_params, self.layer_idx, tmp_view): y2 = self.mixer2(x, inference_params=inference_params, **mixer_kwargs) else: - y1 = self.mixer1(x, inference_params=inference_params, **mixer_kwargs) y2 = self.mixer2(x, inference_params=inference_params, **mixer_kwargs) return y1, y2 @@ -254,11 +281,10 @@ def forward( return hidden_states, residual def allocate_inference_cache(self, batch_size, max_seqlen, dtype=None, **kwargs): - cache1 = getattr(self.mixer1, "allocate_inference_cache", None) - cache2 = getattr(self.mixer2, "allocate_inference_cache", None) - c1 = cache1(batch_size, max_seqlen, dtype=dtype, **kwargs) if callable(cache1) else None - c2 = cache2(batch_size, max_seqlen, dtype=dtype, **kwargs) if callable(cache2) else None - return (c1, c2) + # Share a single cache object between both mixers + cache_fn = getattr(self.mixer1, "allocate_inference_cache", None) + shared = cache_fn(batch_size, max_seqlen, dtype=dtype, **kwargs) if callable(cache_fn) else None + return shared @classmethod def from_pretrained_block( @@ -269,7 +295,7 @@ def from_pretrained_block( norm_cls: Optional[Callable[[int], nn.Module]] = None, fused_add_norm: Optional[bool] = None, residual_in_fp32: Optional[bool] = None, - lambda_init: float = 0.1, + lambda_init: Optional[float] = None, use_postscale: bool = False, device: Optional[torch.device] = None, dtype: Optional[torch.dtype] = None, @@ -286,8 +312,16 @@ def from_pretrained_block( fused_add_norm = fused_add_norm if fused_add_norm is not None else getattr(block, "fused_add_norm", False) residual_in_fp32 = residual_in_fp32 if residual_in_fp32 is not None else getattr(block, "residual_in_fp32", False) + # Try to infer dimension robustly if block doesn't have d_model + dim = getattr(block, "d_model", None) + if dim is None: + if hasattr(block, "norm") and hasattr(block.norm, "weight"): + dim = block.norm.weight.shape[0] + else: + raise ValueError("Cannot infer dim from the provided block") + newb = cls( - dim=block.d_model, + dim=dim, mixer_cls1=mixer_cls, mixer_cls2=mixer_cls, mlp_cls=mlp_cls, @@ -304,10 +338,8 @@ def from_pretrained_block( # copy prenorm if src_norm is not None: newb.norm.load_state_dict(src_norm.state_dict(), strict=False) - # seed post norms with same stats - newb.post_mamba_norm1.load_state_dict(newb.norm.state_dict(), strict=False) - newb.post_mamba_norm2.load_state_dict(newb.norm.state_dict(), strict=False) - newb.post_sub_norm.load_state_dict(newb.norm.state_dict(), strict=False) + # seed sublayer norm with same stats + newb.subln.load_state_dict(newb.norm.state_dict(), strict=False) # copy mixer weights into both mixers if src_mixer is not None: @@ -321,4 +353,4 @@ def from_pretrained_block( if hasattr(block, "norm2") and hasattr(newb, "norm2"): newb.norm2.load_state_dict(block.norm2.state_dict(), strict=False) - return newb + return newb \ No newline at end of file From ff0c29d5e1091358b387ac23163964ce66ddd021 Mon Sep 17 00:00:00 2001 From: Maxim Melichov <80150303+maxmelichov@users.noreply.github.com> Date: Tue, 23 Sep 2025 16:55:34 +0300 Subject: [PATCH 10/10] Refactor cache management for mixer1 and mixer2 --- mamba_ssm/modules/block.py | 64 ++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/mamba_ssm/modules/block.py b/mamba_ssm/modules/block.py index 12ddc7ff1..05b3408eb 100644 --- a/mamba_ssm/modules/block.py +++ b/mamba_ssm/modules/block.py @@ -174,41 +174,45 @@ def _run_mixers(self, x: Tensor, inference_params=None, **mixer_kwargs) -> Tuple y2 = self.mixer2(x, inference_params=None, **mixer_kwargs) return y1, y2 - # Shared cache stored at key = self.layer_idx. Ensure it exists, update shared once via mixer1, - # then run mixer2 against a temporary cloned view to avoid a double persistent update. - slot = inference_params.key_value_memory_dict.get(self.layer_idx, None) - if slot is None: - # Proactively allocate a shared cache so both mixers see the same initial states + # Ensure persistent, SEPARATE cache slots for each branch + ip = inference_params + main_key = self.layer_idx + # Use a hidden negative key for branch 2 to avoid collisions with real layer indices + branch2_key = -(self.layer_idx + 1) + + # Ensure branch 1 cache exists at main_key + slot1 = ip.key_value_memory_dict.get(main_key, None) + if slot1 is None: try: bs = x.shape[0] - max_seqlen = getattr(inference_params, "max_seqlen", None) + max_seqlen = getattr(ip, "max_seqlen", None) dtype = x.dtype if max_seqlen is not None: - inference_params.key_value_memory_dict[self.layer_idx] = self.allocate_inference_cache(bs, max_seqlen, dtype=dtype) - slot = inference_params.key_value_memory_dict.get(self.layer_idx, None) + ip.key_value_memory_dict[main_key] = self.mixer1.allocate_inference_cache(bs, max_seqlen, dtype=dtype) + slot1 = ip.key_value_memory_dict.get(main_key, None) except Exception: - # Fallback: let mixer1 lazily allocate on its own - slot = None - - def _clone_slot(s): - if torch.is_tensor(s): - return s.clone() - if isinstance(s, (tuple, list)): - typ = type(s) - return typ(_clone_slot(t) for t in s) - if isinstance(s, dict): - return {k: _clone_slot(v) for k, v in s.items()} - return s - - # Clone original states BEFORE running mixer1 so both branches see the same pre-update states - tmp_view = _clone_slot(slot) if slot is not None else None - - y1 = self.mixer1(x, inference_params=inference_params, **mixer_kwargs) - if tmp_view is not None: - with DiffBlockPaper._SwapCache(inference_params, self.layer_idx, tmp_view): - y2 = self.mixer2(x, inference_params=inference_params, **mixer_kwargs) + slot1 = None + + # Ensure branch 2 cache exists at branch2_key + slot2 = ip.key_value_memory_dict.get(branch2_key, None) + if slot2 is None: + try: + bs = x.shape[0] + max_seqlen = getattr(ip, "max_seqlen", None) + dtype = x.dtype + if max_seqlen is not None: + ip.key_value_memory_dict[branch2_key] = self.mixer2.allocate_inference_cache(bs, max_seqlen, dtype=dtype) + slot2 = ip.key_value_memory_dict.get(branch2_key, None) + except Exception: + slot2 = None + + # Run branches against their own caches; swap branch2 into the main key during its call + y1 = self.mixer1(x, inference_params=ip, **mixer_kwargs) + if slot2 is not None: + with DiffBlockPaper._SwapCache(ip, main_key, slot2): + y2 = self.mixer2(x, inference_params=ip, **mixer_kwargs) else: - y2 = self.mixer2(x, inference_params=inference_params, **mixer_kwargs) + y2 = self.mixer2(x, inference_params=ip, **mixer_kwargs) return y1, y2 @staticmethod @@ -353,4 +357,4 @@ def from_pretrained_block( if hasattr(block, "norm2") and hasattr(newb, "norm2"): newb.norm2.load_state_dict(block.norm2.state_dict(), strict=False) - return newb \ No newline at end of file + return newb