pmnet-icml2026-10724 commited on
Commit
9c030d6
·
verified ·
1 Parent(s): b1ca1f0

Upload 7 files

Browse files
comparison/config_mamba.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "MambaForCausalLM"
4
+ ],
5
+ "bos_token_id": 0,
6
+ "conv_kernel": 4,
7
+ "d_inner": 1024,
8
+ "d_model": 512,
9
+ "eos_token_id": 0,
10
+ "expand": 2,
11
+ "fused_add_norm": true,
12
+ "hidden_act": "silu",
13
+ "hidden_size": 512,
14
+ "initializer_range": 0.1,
15
+ "intermediate_size": 1024,
16
+ "layer_norm_epsilon": 1e-05,
17
+ "model_type": "mamba",
18
+ "n_layer": 18,
19
+ "num_hidden_layers": 18,
20
+ "pad_token_id": 0,
21
+ "pad_vocab_size_multiple": 8,
22
+ "rescale_prenorm_residual": false,
23
+ "residual_in_fp32": true,
24
+ "rms_norm": true,
25
+ "ssm_cfg": {},
26
+ "state_size": 16,
27
+ "time_step_floor": 0.0001,
28
+ "time_step_init_scheme": "random",
29
+ "time_step_max": 0.1,
30
+ "time_step_min": 0.001,
31
+ "time_step_rank": 32,
32
+ "time_step_scale": 1.0,
33
+ "torch_dtype": "bfloat16",
34
+ "use_bias": false,
35
+ "use_cache": true,
36
+ "use_conv_bias": true,
37
+ "vocab_size": 264
38
+ }
comparison/config_pmnet.json ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "PMNetForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.1,
7
+ "bos_token_id": 0,
8
+ "dtype": "bfloat16",
9
+ "eos_token_id": 0,
10
+ "head_dim": 64,
11
+ "hidden_act": "silu",
12
+ "hidden_size": 384,
13
+ "initializer_range": 0.02,
14
+ "intermediate_size": 1024,
15
+ "layer_types": [
16
+ "sliding_attention",
17
+ "sliding_attention",
18
+ "sliding_attention",
19
+ "sliding_attention",
20
+ "sliding_attention",
21
+ "sliding_attention",
22
+ "sliding_attention",
23
+ "sliding_attention",
24
+ "sliding_attention",
25
+ "sliding_attention",
26
+ "sliding_attention",
27
+ "sliding_attention"
28
+ ],
29
+ "max_position_embeddings": 40960,
30
+ "max_window_layers": 0,
31
+ "memory_cumsum": true,
32
+ "memory_size": 32,
33
+ "memory_write_period": 3,
34
+ "model_type": "pmnet",
35
+ "num_attention_heads": 12,
36
+ "num_hidden_layers": 12,
37
+ "num_key_value_heads": 12,
38
+ "num_memory": 4,
39
+ "num_memory_read_heads": 4,
40
+ "rms_norm_eps": 1e-06,
41
+ "rope_scaling": null,
42
+ "rope_theta": 1000000,
43
+ "sliding_window": 128,
44
+ "tie_word_embeddings": true,
45
+ "transformers_version": "4.57.6",
46
+ "use_cache": false,
47
+ "use_sliding_window": true,
48
+ "vocab_size": 264,
49
+ "auto_map": {
50
+ "AutoConfig": "configuration_pmnet.PMNetConfig",
51
+ "AutoModel": "modeling_pmnet.PMNetModel",
52
+ "AutoModelForCausalLM": "modeling_pmnet.PMNetForCausalLM",
53
+ "AutoTokenizer": [
54
+ "tokenization_pmnet.ByteTokenizer",
55
+ null
56
+ ]
57
+ }
58
+ }
comparison/config_pmnet_no_mem.json ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "PMNetForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.1,
7
+ "bos_token_id": 0,
8
+ "dtype": "bfloat16",
9
+ "eos_token_id": 0,
10
+ "head_dim": 64,
11
+ "hidden_act": "silu",
12
+ "hidden_size": 384,
13
+ "initializer_range": 0.02,
14
+ "intermediate_size": 1024,
15
+ "layer_types": [
16
+ "sliding_attention",
17
+ "sliding_attention",
18
+ "sliding_attention",
19
+ "sliding_attention",
20
+ "sliding_attention",
21
+ "sliding_attention",
22
+ "sliding_attention",
23
+ "sliding_attention",
24
+ "sliding_attention",
25
+ "sliding_attention",
26
+ "sliding_attention",
27
+ "sliding_attention"
28
+ ],
29
+ "max_position_embeddings": 40960,
30
+ "max_window_layers": 0,
31
+ "memory_cumsum": false,
32
+ "memory_size": 32,
33
+ "memory_write_period": 3,
34
+ "model_type": "pmnet",
35
+ "num_attention_heads": 12,
36
+ "num_hidden_layers": 12,
37
+ "num_key_value_heads": 12,
38
+ "num_memory": 4,
39
+ "num_memory_read_heads": 4,
40
+ "rms_norm_eps": 1e-06,
41
+ "rope_scaling": null,
42
+ "rope_theta": 1000000,
43
+ "sliding_window": 128,
44
+ "tie_word_embeddings": true,
45
+ "transformers_version": "4.57.6",
46
+ "use_cache": false,
47
+ "use_sliding_window": true,
48
+ "vocab_size": 264,
49
+ "auto_map": {
50
+ "AutoConfig": "configuration_pmnet.PMNetConfig",
51
+ "AutoModel": "modeling_pmnet.PMNetModel",
52
+ "AutoModelForCausalLM": "modeling_pmnet.PMNetForCausalLM",
53
+ "AutoTokenizer": [
54
+ "tokenization_pmnet.ByteTokenizer",
55
+ null
56
+ ]
57
+ }
58
+ }
comparison/config_smollm.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "llama-30M-config",
3
+ "architectures": [
4
+ "LlamaForCausalLM"
5
+ ],
6
+ "attention_bias": false,
7
+ "attention_dropout": 0.1,
8
+ "bos_token_id": 0,
9
+ "eos_token_id": 0,
10
+ "hidden_act": "silu",
11
+ "hidden_size": 384,
12
+ "initializer_range": 0.02,
13
+ "intermediate_size": 1024,
14
+ "max_position_embeddings": 8192,
15
+ "mlp_bias": false,
16
+ "model_type": "llama",
17
+ "num_attention_heads": 12,
18
+ "num_hidden_layers": 16,
19
+ "num_key_value_heads": 4,
20
+ "pretraining_tp": 1,
21
+ "rms_norm_eps": 1e-05,
22
+ "rope_scaling": null,
23
+ "rope_theta": 10000.0,
24
+ "tie_word_embeddings": true,
25
+ "torch_dtype": "bfloat16",
26
+ "transformers_version": "4.41.2",
27
+ "use_cache": true,
28
+ "vocab_size": 264
29
+ }
comparison/fineweb-edu_1B_2048.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import wandb
3
+ import os
4
+ os.environ["HF_HOME"] = "/root/hf_cache"
5
+ os.environ["HF_DATASETS_CACHE"] = "/root/hf_cache/datasets"
6
+ from transformers import AutoTokenizer
7
+ NUM_PROC = 16
8
+ BLOCK_SIZE = 2048
9
+ DATA_DIR = "/data/fineweb_edu_byte_1B_2048"
10
+ SHARD_START_INDEX = 0
11
+ SHARD_LEN = 1
12
+ DATA_PROCESS_BATCH_SIZE=5000
13
+ dataset_base_url = "https://huggingface.co/datasets/HuggingFaceFW/fineweb-edu/resolve/main/sample/10BT"
14
+
15
+ from datasets import load_dataset, load_from_disk
16
+ from itertools import chain
17
+
18
+
19
+ from typing import Dict, List, Optional, Any
20
+
21
+ tokenizer = AutoTokenizer.from_pretrained("google/byt5-small")
22
+
23
+ train_files = {
24
+ "train": [
25
+ f"{dataset_base_url}/{i:03d}_00000.parquet" for i in range(SHARD_START_INDEX, SHARD_START_INDEX+SHARD_LEN)
26
+ ]
27
+ }
28
+ raw_train = load_dataset("parquet", data_files=train_files, split="train") # FIXME
29
+
30
+ val_files = {"train": f"{dataset_base_url}/013_00000.parquet"}
31
+ raw_val = load_dataset("parquet", data_files=val_files, split="train") # FIXME
32
+
33
+ def process_batch(examples):
34
+ tokenized = tokenizer(examples["text"], add_special_tokens=False)
35
+ input_ids = tokenized["input_ids"]
36
+
37
+ eos_id = tokenizer.eos_token_id
38
+ concatenated_ids = list(chain.from_iterable(ids + [eos_id] for ids in input_ids))
39
+
40
+ total_length = len(concatenated_ids)
41
+ total_length = (total_length // BLOCK_SIZE) * BLOCK_SIZE
42
+
43
+ result = {
44
+ "input_ids": [
45
+ concatenated_ids[i : i + BLOCK_SIZE]
46
+ for i in range(0, total_length, BLOCK_SIZE)
47
+ ]
48
+ }
49
+ return result
50
+
51
+ column_names = raw_train.column_names
52
+
53
+ print(f"Processing Train dataset using {NUM_PROC} processes...")
54
+ lm_dataset_train = raw_train.map(
55
+ process_batch,
56
+ batched=True,
57
+ batch_size=DATA_PROCESS_BATCH_SIZE,
58
+ remove_columns=column_names,
59
+ num_proc=NUM_PROC,
60
+ desc="Tokenizing & Grouping Train"
61
+ )
62
+
63
+ print("Processing Val dataset...")
64
+ lm_dataset_val = raw_val.map(
65
+ process_batch,
66
+ batched=True,
67
+ batch_size=DATA_PROCESS_BATCH_SIZE,
68
+ remove_columns=column_names,
69
+ num_proc=NUM_PROC,
70
+ desc="Tokenizing & Grouping Val"
71
+ )
72
+
73
+ os.makedirs(DATA_DIR, exist_ok=True)
74
+
75
+ print(f"Saving to {DATA_DIR}...")
76
+ TARGET_BLOCKS_TRAIN = 250_000
77
+ TARGET_BLOCKS_VAL = 1_250
78
+ TARGET_BLOCKS_TEST = 50_000
79
+
80
+ lm_dataset_train = lm_dataset_train.select(range(TARGET_BLOCKS_TRAIN))
81
+ lm_dataset_test = lm_dataset_val.select(range(TARGET_BLOCKS_TEST))
82
+ lm_dataset_val = lm_dataset_val.select(range(TARGET_BLOCKS_TEST, TARGET_BLOCKS_TEST + TARGET_BLOCKS_VAL))
83
+
84
+ print(f"Saving finalized datasets to {DATA_DIR}...")
85
+ os.makedirs(DATA_DIR, exist_ok=True)
86
+ lm_dataset_train.save_to_disk(f"{DATA_DIR}/train")
87
+ lm_dataset_val.save_to_disk(f"{DATA_DIR}/val")
88
+ lm_dataset_test.save_to_disk(f"{DATA_DIR}/test")
89
+
90
+ ds_train = load_from_disk(f"{DATA_DIR}/train")
91
+ print(f"Final Train blocks count: {len(ds_train)}")
92
+ ds_val = load_from_disk(f"{DATA_DIR}/val")
93
+ print(f"Final Val blocks count: {len(ds_val)}")
94
+ ds_test = load_from_disk(f"{DATA_DIR}/test")
95
+ print(f"Final Test blocks count: {len(ds_test)}")
comparison/install_dependency.sh ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ pip install transformers[torch]==4.57.6
2
+ pip install wandb datasets einops hf_transfer accelerate https://github.com/Dao-AILab/flash-attention/releases/download/v2.8.3/flash_attn-2.8.3+cu12torch2.8cxx11abiTRUE-cp312-cp312-linux_x86_64.whl https://github.com/state-spaces/mamba/releases/download/v2.3.1/mamba_ssm-2.3.1+cu12torch2.8cxx11abiTRUE-cp312-cp312-linux_x86_64.whl https://github.com/Dao-AILab/causal-conv1d/releases/download/v1.6.1.post4/causal_conv1d-1.6.1+cu12torch2.8cxx11abiTRUE-cp312-cp312-linux_x86_64.whl
comparison/train_comparison.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import torch
4
+ import wandb
5
+ from datasets import load_from_disk
6
+ from transformers import (
7
+ Trainer,
8
+ TrainingArguments,
9
+ DataCollatorForLanguageModeling,
10
+ set_seed,
11
+ get_cosine_schedule_with_warmup,
12
+ AutoModelForCausalLM, AutoTokenizer,AutoConfig
13
+ )
14
+ from torch.optim import AdamW
15
+
16
+ # MODEL_ID = "pmnet-icml2026-10724/pmnet"
17
+ # CONFIG_PATH = "/workspace/scripts/config_pmnet.json"
18
+ # CKPT_SAVE_DIR = "/workspace/ckpts/pmnet"
19
+ # compile_model = True
20
+
21
+ # MODEL_ID = "state-spaces/mamba-130m-hf"
22
+ # CONFIG_PATH = "/workspace/scripts/config_mamba.json"
23
+ # CKPT_SAVE_DIR = "/workspace/ckpts/mamba"
24
+ # compile_model = False
25
+
26
+ # MODEL_ID = "HuggingFaceTB/SmolLM-135M"
27
+ # CONFIG_PATH = "/workspace/scripts/config_smollm.json"
28
+ # CKPT_SAVE_DIR = "/workspace/ckpts/smollm"
29
+ # compile_model = True
30
+
31
+ MODEL_ID = "pmnet-icml2026-10724/pmnet"
32
+ CONFIG_PATH = "/workspace/scripts/config_pmnet_no_mem.json"
33
+ CKPT_SAVE_DIR = "/workspace/ckpts/pmnet_no_mem"
34
+ compile_model = True
35
+
36
+ ########################################################################
37
+
38
+ DATA_DIR = "/data/fineweb_edu_byte_1B_2048"
39
+ SEED = 42
40
+
41
+ BATCH_SIZE = 48
42
+ GRADIENT_ACCUMULATION_STEPS = 1
43
+ NUM_DEVICES = 2
44
+
45
+ os.environ["WANDB_PROJECT"] = "pmnet_comparison"
46
+
47
+ ########################################################################
48
+
49
+ per_device_batch_size = BATCH_SIZE // (NUM_DEVICES*GRADIENT_ACCUMULATION_STEPS)
50
+
51
+
52
+ def get_optimizer_grouped_parameters(model, weight_decay: float):
53
+ no_decay_keywords = ["bias", "norm", "embedding", "layernorm", "a_log"]
54
+ decay_params = []
55
+ no_decay_params = []
56
+
57
+ for name, param in model.named_parameters():
58
+ if not param.requires_grad: continue
59
+ if any(keyword in name.lower() for keyword in no_decay_keywords):
60
+ no_decay_params.append(param)
61
+ else:
62
+ decay_params.append(param)
63
+ return [
64
+ {"params": decay_params, "weight_decay": weight_decay},
65
+ {"params": no_decay_params, "weight_decay": 0.0},
66
+ ]
67
+
68
+ def main():
69
+ set_seed(SEED)
70
+
71
+
72
+ config = AutoConfig.from_pretrained(MODEL_ID, trust_remote_code=True)
73
+ if CONFIG_PATH and os.path.exists(CONFIG_PATH):
74
+ with open(CONFIG_PATH, "r", encoding="utf-8") as f:
75
+ local_config_dict = json.load(f)
76
+ config.update(local_config_dict)
77
+ model = AutoModelForCausalLM.from_config(config, trust_remote_code=True)
78
+
79
+ # model size
80
+ total_params = sum(p.numel() for p in model.parameters())
81
+ print(f"Total params: {total_params/1_000_000}")
82
+
83
+ dataset_train = load_from_disk(os.path.join(DATA_DIR, "train"))
84
+ dataset_val = load_from_disk(os.path.join(DATA_DIR, "val"))
85
+
86
+ tokenizer = AutoTokenizer.from_pretrained("google/byt5-small")
87
+
88
+ training_args = TrainingArguments(
89
+ output_dir=CKPT_SAVE_DIR,
90
+ overwrite_output_dir=False,
91
+ num_train_epochs=1,
92
+
93
+ save_strategy="steps",
94
+ save_steps=500,
95
+ eval_strategy="steps",
96
+ eval_steps=250,
97
+ logging_strategy="steps",
98
+ logging_steps=10,
99
+ save_total_limit=2,
100
+
101
+ load_best_model_at_end=True,
102
+ metric_for_best_model="loss",
103
+ greater_is_better=False,
104
+
105
+ seed=SEED,
106
+ data_seed=SEED,
107
+
108
+ per_device_train_batch_size=per_device_batch_size,
109
+ per_device_eval_batch_size=per_device_batch_size,
110
+ gradient_accumulation_steps=GRADIENT_ACCUMULATION_STEPS,
111
+
112
+ learning_rate=1e-4,
113
+ max_grad_norm=1.0,
114
+ fp16=False,
115
+ bf16=True,
116
+
117
+ dataloader_num_workers=8,
118
+ report_to="wandb",
119
+ ddp_find_unused_parameters=False,
120
+
121
+ lr_scheduler_type="cosine",
122
+ warmup_steps=500,
123
+ torch_compile=compile_model
124
+ )
125
+
126
+ data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)
127
+
128
+ optimizer_grouped_parameters = get_optimizer_grouped_parameters(model, weight_decay=0.1)
129
+ optimizer = AdamW(optimizer_grouped_parameters, lr=training_args.learning_rate, betas=(0.9, 0.95))
130
+
131
+ trainer = Trainer(
132
+ model=model,
133
+ args=training_args,
134
+ train_dataset=dataset_train,
135
+ eval_dataset=dataset_val,
136
+ data_collator=data_collator,
137
+ optimizers=(optimizer, None),
138
+ )
139
+ trainer.train()
140
+ trainer.save_model(os.path.join(CKPT_SAVE_DIR, "final_model"))
141
+
142
+ if __name__ == "__main__":
143
+ main()