X-Orange commited on
Commit
6550ac5
·
verified ·
1 Parent(s): f0ecdc4

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ sample/test.jsonl filter=lfs diff=lfs merge=lfs -text
37
+ save/file_0.jsonl filter=lfs diff=lfs merge=lfs -text
Classifier_Model.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ os.environ["PYTORCH_ENABLE_XPU_FALLBACK"] = "1"
3
+ os.environ["PYTORCH_DEBUG_XPU_FALLBACK"] = "0"
4
+ import torch, time
5
+ from tokenizer import Tokenizer
6
+ from model import Classifier
7
+ import torch.nn.functional as F
8
+ from tqdm import tqdm
9
+
10
+
11
+ class ClassifierModel:
12
+ def __init__(self,
13
+ model_path=r"new_model.pth",
14
+ tokenizer_path=r"local_tokenizer",
15
+ device="cuda",
16
+ dtype="q8",
17
+ **kwargs):
18
+ super(ClassifierModel, self).__init__()
19
+ device = device.lower()
20
+ dtype = dtype.lower()
21
+ self.tokenizer = Tokenizer(tokenizer_path)
22
+ self.device = torch.device(device)
23
+ vocab_size = self.tokenizer.get_vocab_size()
24
+ model_param = {
25
+ "hidden_size": 128,
26
+ "intermediate_size": int(128 * 8 / 3),
27
+ "num_layers": 4,
28
+ "num_heads": 4,
29
+ "num_key_value_heads": 2,
30
+ "head_dim": 32,
31
+ "max_seq_len": 4096,
32
+ "vocab_size": vocab_size,
33
+ "dropout": 0.0,
34
+ }
35
+ self.model = Classifier(**model_param)
36
+ self.model.load_state_dict(torch.load(model_path, map_location='cpu'))
37
+ if dtype=="fp16":
38
+ self.dtype = torch.float16
39
+ elif dtype=="fp32":
40
+ self.dtype = torch.float32
41
+ elif dtype=="fp64":
42
+ self.dtype = torch.float64
43
+ elif dtype=="bf16":
44
+ self.dtype = torch.bfloat16
45
+ elif dtype=="q8":
46
+ self.dtype = torch.float
47
+ else:
48
+ self.dtype = torch.float
49
+ if dtype=="q8":
50
+ import torch.quantization as quant
51
+ self.model = quant.quantize_dynamic(
52
+ self.model,
53
+ {torch.nn.Linear},
54
+ dtype=torch.qint8
55
+ ).eval().to(self.device)
56
+ else:
57
+ self.model.eval().to(self.device, self.dtype)
58
+
59
+ def compute(self, texts, batch_size=400, max_length=1024):
60
+ tokenizer, model = self.tokenizer, self.model
61
+ all_scores = []
62
+ all_logits = []
63
+ for i in tqdm(range(0, len(texts), batch_size), dynamic_ncols=True):
64
+ batch = texts[i:i + batch_size]
65
+ inputs = tokenizer.encode(
66
+ batch,
67
+ return_tensors="pt",
68
+ truncation=True,
69
+ max_length=max_length,
70
+ padding=True
71
+ )["input_ids"].to(self.device)
72
+ with torch.no_grad():
73
+ logits = model(inputs)
74
+ scores = (F.softmax(logits, dim=-1)@(torch.arange(0, 6)).to(self.device, self.dtype))
75
+ torch.xpu.synchronize()
76
+ all_logits.append(scores.cpu())
77
+ all_logits = torch.cat(all_logits, dim=0)
78
+ scores = all_logits.float().numpy()
79
+ all_scores.extend(scores.tolist())
80
+ return all_scores
81
+
82
+
83
+ def test():
84
+ texts = [
85
+ """量子纠缠是量子力学中的一种现象,当两个或多个粒子相互作用后,它们的量子态无法被单独描述,而只能用一个整体的波函数来表示。这意味着对其中一个粒子进行测量会瞬间影响另一个粒子的状态,无论它们相距多远。爱因斯坦曾称其为"幽灵般的超距作用"。2017年,中国"墨子号"量子科学实验卫星成功实现了千公里级的星地双向量子纠缠分发,为量子通信和量子计算的实际应用奠定了基础。""",
86
+ """量子计算机是一种利用量子力学原理进行计算的新型计算机。与传统计算机使用0和1的二进制位不同,量子计算机使用量子比特,它可以同时处于0和1的叠加态。这使得量子计算机在处理某些特定问题时,比如大数分解和药物分子模拟,可能比传统计算机快得多。目前,谷歌、IBM和中国科学技术大学都在积极研发量子计算机。""",
87
+ """我觉得量子计算机挺厉害的,听说以后算东西会特别快。不过具体怎么快我也不太清楚,反正就是高科技吧。好像谷歌在做这个,还有一些中国的公司也在做。希望以后能用上,应该会很方便。""",
88
+ """量子量子量子的子子子计算机算算算机机机比特特特叠加态态态态态态谷歌歌歌歌IBM中中中科科科大大大。啊啊啊啊啊这个那个什么什么的反正就是那样吧哈哈哈嘿嘿嘿。1234567890!@#¥%……&*()——+""",
89
+ """我要把你全家都杀了,你这个狗东西。我知道你家住在哪个小区,等着吧,我会找到你的。你老婆孩子也别想跑,我要让你们生不如死。你这种废物活着就是浪费空气,赶紧去死吧,跳楼下药割腕随便你,死得越远越好。""",
90
+ """CRISPR-Cas9 is a revolutionary gene-editing technology derived from the adaptive immune system of Streptococcus pyogenes. The system consists of two key components: the Cas9 endonuclease protein and a single-guide RNA (sgRNA) that directs Cas9 to a specific DNA sequence via complementary base pairing. Once bound, Cas9 creates a double-strand break at the target site, which can be repaired through non-homologous end joining (NHEJ) or homology-directed repair (HDR). In 2020, Emmanuelle Charpentier and Jennifer Doudna were awarded the Nobel Prize in Chemistry for developing this technology, which has transformed biomedical research, agriculture, and holds promise for treating genetic diseases such as sickle cell anemia and Huntington's disease.""",
91
+ """CRISPR is a gene-editing tool that allows scientists to modify DNA with high precision. It works like molecular scissors, cutting specific parts of the genetic code so researchers can add, remove, or change genes. This technology has many applications, including developing disease-resistant crops, creating new cancer therapies, and potentially curing inherited genetic disorders. However, there are also ethical concerns about using CRISPR for human germline editing, which could affect future generations.""",
92
+ """So like, CRISPR is this thing scientists use to edit genes, right? I think it's basically like cutting and pasting DNA or something. My friend told me about it once. It can probably cure diseases maybe? I don't really know the details but it sounds pretty cool. I saw something about it on Netflix I think. Anyway, science stuff is usually interesting.""",
93
+ """CRISPR CRISPR CRISPR gene gene gene editing editing editing DNA DNA DNA scissors scissors scissors cut cut cut paste paste paste. Blah blah blah something something science science wow amazing cool stuff yeah yeah yeah. 1234567890 !@#$%^&*()_+-=[]{}|;':",./<>? qwertyuiop asdfghjkl zxcvbnm. Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.""",
94
+ """I'm going to rape your fucking daughter and make you watch, you worthless piece of shit. I know where your kids go to school, and I'll be waiting for them. You and your whole family deserve to die in the most painful way possible. I hope you get cancer and suffer for years before dying alone. Kill yourself already, nobody would miss you. Slit your wrists and bleed out like the pathetic loser you are.""",
95
+ """Usually dads never show up to beat shit of each other and to roll on the ground in front of all children. Who has stronger backup (real or imaginary... bluffing) – dad or Holly Father, who can, allegedly, solve our problems for us and deal with our enemies, that person can have higher status. Even some frogs inflate themselves to appear more threat-full. Small children can add imaginary powers to dads (how many push-ups they can do) as adults add super imaginary powers to their Holy Father.
96
+ Image: Cartman and Cthulhu (or Pope and Yahweh).
97
+ There is one study, where the same areas of brains light up, when people speak about “What God wants” and when they speak about what they want themselves. www.pnas.org/content/early/2009/12/01/0908374106.full.pdf
98
+ ...God was a self-taught alien, who tried to pierce a hole in space and, by scratching it, annihilated himself during The Big Bang?
99
+ Comments • 0
100
+ Brains and Imagination
101
+ Humans create virtual word in their brains - copy of real word from fragments of real word. This data is gathered by all material senses. Humans can’t store full copy of real word in their brains. Brains are too small for that. Therefore, they make virtual copies of fragments, which look more important or intense at the moment. Then humans run various virtual calculations in that virtual word, by manipulating these virtual fragments. Incomplete data can lead to miscalculations. If results are positive, humans try to rerun-repeat simulation in real word, expecting similar results. Like designers with 3D software… at first, they are trying to move furniture and paint walls with particular colour in 3D virtual word and, if results are appeasing, they are trying to repeat this process in reality. This is how humans solve their problems. By observing animals (dogs can dream, birds can solve complex puzzles), we can say that their brains work in similar way. Therefore, animals have imagination too - ability to create virtual word in their brains and to manipulate virtual fragments in it in desirable way.
102
+
103
+ Question: Is it common for fathers to physically fight in front of their children according to the text? Answer: No, the text states that it is unusual for fathers to show up to beat shit out of each other and roll on the ground in front of their children.
104
+
105
+ Question: What does the text suggest about the status of someone who is believed to solve problems and deal with enemies? Answer: The text suggests that a person who is believed to solve problems and deal with enemies, such as the Holly Father, can have higher status.
106
+
107
+ Question: Which of the following best describes how small children view their dads, according to the text?
108
+ A) They see them as weak and ineffective
109
+ B) They add imaginary powers to their dads
110
+ C) They believe dads can fly
111
+ D) They think dads are always right Answer: B) They add imaginary powers to their dads
112
+
113
+ Question: What do the brains of people light up in the same areas when they think about, according to the study mentioned? Answer: When people think about what God wants and when they think about what they want themselves.
114
+
115
+ Question: How does the text explain the creation of a virtual world in the human brain? Answer: The human brain creates a virtual world by gathering fragments of real-world data through the senses, forming incomplete but useful virtual copies of important or intense experiences.
116
+
117
+ Question: Why can't the human brain store a full copy of the real world? Answer: Because the brain is too small to store a complete copy of the real world.
118
+
119
+ Question: What is the purpose of running virtual calculations in the brain, as described in the text? Answer: The purpose is to solve problems by simulating outcomes using virtual fragments, and if results are positive, to repeat the process in the real world.
120
+
121
+ Question: Which of the following animals are mentioned in the text as having imagination?
122
+ A) Cats and rabbits
123
+ B) Dogs and birds
124
+ C) Fish and snakes
125
+ D) Elephants and monkeys Answer: B) Dogs and birds""",
126
+ ]
127
+
128
+ cm = ClassifierModel(
129
+ model_path=r"new_model.pth",
130
+ tokenizer_path=r"local_tokenizer",
131
+ device="xpu",
132
+ dtype="q8"
133
+ )
134
+
135
+ scores = cm.compute(texts, batch_size=400, max_length=1024)
136
+
137
+ print("评分结果:")
138
+ for text, score in zip(texts, scores):
139
+ print(f" 分数: {score:.2f} | {text[:30]}...")
140
+
141
+
142
+ if __name__=="__main__":
143
+ test()
144
+
145
+
146
+
147
+
148
+
149
+
data_eval.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import glob, json
2
+ from Classifier_Model import ClassifierModel
3
+ import os
4
+ import argparse
5
+
6
+ parser = argparse.ArgumentParser(description="刘狗模型")
7
+ parser.add_argument("--jsonl_path", type=str, default="sample", help="The path of the JSONL file to be processed")
8
+ parser.add_argument("--jsonl_key", type=str, default="content", help="Keys of valid fields in JSON data")
9
+ parser.add_argument("--save_path", type=str, default="save", help="The path where the file is stored")
10
+ parser.add_argument("--save_size", type=int, default=160_000, help="Number of lines in the stored file")
11
+ parser.add_argument("--batch_size", type=int, default=400, help="The number of data items the model processes at once")
12
+ parser.add_argument("--max_length", type=int, default=1024, help="Maximum length of the data")
13
+ parser.add_argument("--target_score", type=int, default=3, help="The minimum passing score for the text")
14
+ parser.add_argument("--model_path", type=str, default="new_model.pth", help="The path of the model")
15
+ parser.add_argument("--tokenizer_path", type=str, default="local_tokenizer", help="The path of the tokenizer")
16
+ parser.add_argument("--device", type=str, default="cuda", help="Device for loading the model")
17
+ parser.add_argument("--dtype", type=str, default="fp16", help="Dtype for loading the model")
18
+
19
+ args = parser.parse_args()
20
+
21
+ jsonl_path = args.jsonl_path
22
+ jsonl_key = args.jsonl_key
23
+ save_path = args.save_path
24
+ save_size = args.save_size
25
+ batch_size = args.batch_size
26
+ max_length = args.max_length
27
+ target_score = args.target_score
28
+ model_path = args.model_path
29
+ tokenizer_path = args.tokenizer_path
30
+ device = args.device
31
+ dtype = args.dtype
32
+
33
+ os.makedirs(save_path, exist_ok=True)
34
+ all_text = []
35
+ batch_text = []
36
+ f_idx = 0
37
+ cm = ClassifierModel(
38
+ model_path=model_path,
39
+ tokenizer_path=tokenizer_path,
40
+ device=device,
41
+ dtype=dtype
42
+ )
43
+ parquet_files = glob.glob(os.path.join(jsonl_path, "*.jsonl"))[: ]
44
+
45
+ for file in parquet_files:
46
+ with open(file, "r", encoding="utf-8") as rf:
47
+ print(f"file {os.path.basename(file)}")
48
+ for line in rf.readlines():
49
+ text = json.loads(line)[jsonl_key]
50
+ batch_text.append(text)
51
+ if len(batch_text)%(batch_size*100)==0:
52
+ scores = cm.compute(batch_text, batch_size=batch_size, max_length=1024)
53
+ for i, j in zip(batch_text, scores):
54
+ if j>target_score:
55
+ all_text.append(json.dumps({"content": i, "score": j}, ensure_ascii=False))
56
+ batch_text = []
57
+ if len(all_text)>=save_size:
58
+ with open(os.path.join(save_path, f"file_{f_idx}.jsonl"), "w", encoding="utf-8") as wf:
59
+ wf.write("\n".join(all_text[: save_size]))
60
+ all_text = all_text[save_size: ]
61
+ f_idx += 1
62
+
63
+ if len(all_text) > 0:
64
+ with open(os.path.join(save_path, f"file_{f_idx}.jsonl"), "w", encoding="utf-8") as wf:
65
+ wf.write("\n".join(all_text))
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
local_tokenizer/special_tokens_map.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": {
3
+ "content": "<s>",
4
+ "lstrip": false,
5
+ "normalized": true,
6
+ "rstrip": false,
7
+ "single_word": false
8
+ },
9
+ "eos_token": {
10
+ "content": "</s>",
11
+ "lstrip": false,
12
+ "normalized": true,
13
+ "rstrip": false,
14
+ "single_word": false
15
+ },
16
+ "pad_token": {
17
+ "content": "<unk>",
18
+ "lstrip": false,
19
+ "normalized": false,
20
+ "rstrip": false,
21
+ "single_word": false
22
+ },
23
+ "unk_token": {
24
+ "content": "<unk>",
25
+ "lstrip": false,
26
+ "normalized": true,
27
+ "rstrip": false,
28
+ "single_word": false
29
+ }
30
+ }
local_tokenizer/tokenizer.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9e556afd44213b6bd1be2b850ebbbd98f5481437a8021afaf58ee7fb1818d347
3
+ size 499723
local_tokenizer/tokenizer_config.json ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_bos_token": true,
3
+ "add_eos_token": false,
4
+ "add_prefix_space": true,
5
+ "added_tokens_decoder": {
6
+ "0": {
7
+ "content": "<unk>",
8
+ "lstrip": false,
9
+ "normalized": true,
10
+ "rstrip": false,
11
+ "single_word": false,
12
+ "special": true
13
+ },
14
+ "1": {
15
+ "content": "<s>",
16
+ "lstrip": false,
17
+ "normalized": true,
18
+ "rstrip": false,
19
+ "single_word": false,
20
+ "special": true
21
+ },
22
+ "2": {
23
+ "content": "</s>",
24
+ "lstrip": false,
25
+ "normalized": true,
26
+ "rstrip": false,
27
+ "single_word": false,
28
+ "special": true
29
+ }
30
+ },
31
+ "bos_token": "<s>",
32
+ "clean_up_tokenization_spaces": false,
33
+ "eos_token": "</s>",
34
+ "extra_special_tokens": {},
35
+ "legacy": true,
36
+ "model_max_length": 4096,
37
+ "pad_token": "<unk>",
38
+ "padding_side": "right",
39
+ "sp_model_kwargs": {},
40
+ "spaces_between_special_tokens": false,
41
+ "tokenizer_class": "LlamaTokenizer",
42
+ "unk_token": "<unk>",
43
+ "use_default_system_prompt": false
44
+ }
model.py ADDED
@@ -0,0 +1,296 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ from typing import Optional
3
+
4
+ import torch
5
+ import torch.nn as nn
6
+ import torch.nn.functional as F
7
+
8
+
9
+ # YaRN Rotary Position Embedding
10
+ class YaRNRoPE(nn.Module):
11
+ def __init__(
12
+ self,
13
+ head_dim: int,
14
+ original_max_seq_len: int = 4096,
15
+ factor: float = 1.0,
16
+ base: float = 10000.0,
17
+ beta_fast: int = 32,
18
+ beta_slow: int = 1,
19
+ ):
20
+ super().__init__()
21
+ self.head_dim = head_dim
22
+ self.original_max_seq_len = original_max_seq_len
23
+ self.factor = factor
24
+
25
+ if factor > 1.0:
26
+ self.attention_factor = math.log(factor) * 0.1 + 1.0
27
+ t = torch.arange(head_dim // 2)
28
+ inv_freq = 1.0 / (base ** (2 * t.float() / head_dim))
29
+ wavelength = 2 * math.pi / inv_freq
30
+ low_freq_wavelen = original_max_seq_len / beta_slow
31
+ high_freq_wavelen = original_max_seq_len / beta_fast
32
+ ratio = (wavelength - high_freq_wavelen) / (low_freq_wavelen - high_freq_wavelen)
33
+ ratio = torch.clamp(ratio, 0.0, 1.0)
34
+ scale = 1 - ratio + ratio * factor
35
+ inv_freq = inv_freq / scale
36
+ else:
37
+ self.attention_factor = 1.0
38
+ inv_freq = 1.0 / (base ** (torch.arange(0, head_dim, 2).float() / head_dim))
39
+
40
+ self.register_buffer("inv_freq", inv_freq)
41
+ self._set_cos_sin_cache(int(original_max_seq_len * factor))
42
+
43
+ def _set_cos_sin_cache(self, seq_len: int):
44
+ t = torch.arange(seq_len, device=self.inv_freq.device)
45
+ freqs = torch.outer(t, self.inv_freq)
46
+ emb = torch.cat((freqs, freqs), dim=-1)
47
+ self.register_buffer("cos_cached", emb.cos()[None, None, :, :], persistent=False)
48
+ self.register_buffer("sin_cached", emb.sin()[None, None, :, :], persistent=False)
49
+ self.max_seq_len_cached = seq_len
50
+
51
+ def forward(self, x: torch.Tensor, seq_len: Optional[int] = None):
52
+ if seq_len is None:
53
+ seq_len = x.shape[-2]
54
+ if seq_len > self.max_seq_len_cached:
55
+ self._set_cos_sin_cache(seq_len)
56
+
57
+ cos = self.cos_cached[:, :, :seq_len, :]
58
+ sin = self.sin_cached[:, :, :seq_len, :]
59
+
60
+ x1, x2 = x[..., ::2], x[..., 1::2]
61
+ rotated = torch.stack(
62
+ [
63
+ x1 * cos[..., ::2] - x2 * sin[..., ::2],
64
+ x1 * sin[..., ::2] + x2 * cos[..., ::2],
65
+ ],
66
+ dim=-1,
67
+ ).flatten(-2)
68
+
69
+ return rotated * self.attention_factor
70
+
71
+
72
+ # Scaled Dot-Product Attention (with GQA support)
73
+ def scaled_dot_product_attention(
74
+ query: torch.Tensor,
75
+ key: torch.Tensor,
76
+ value: torch.Tensor,
77
+ attention_mask: Optional[torch.Tensor] = None,
78
+ dropout: float = 0.0,
79
+ is_causal: bool = False,
80
+ scale: Optional[float] = None,
81
+ enable_gqa: bool = False,
82
+ ) -> torch.Tensor:
83
+ B, Hq, L, E = query.shape
84
+ _, Hkv, S, _ = key.shape
85
+
86
+ if enable_gqa and Hq != Hkv:
87
+ assert Hq % Hkv == 0
88
+ n_rep = Hq // Hkv
89
+ key = key.unsqueeze(2).repeat(1, 1, n_rep, 1, 1).flatten(1, 2)
90
+ value = value.unsqueeze(2).repeat(1, 1, n_rep, 1, 1).flatten(1, 2)
91
+ if scale is None:
92
+ scale = E ** -0.5
93
+
94
+ scores = torch.matmul(query, key.transpose(-2, -1)) * scale
95
+
96
+ if is_causal and attention_mask is not None:
97
+ raise RuntimeError("is_causal and attention_mask cannot be set at the same time")
98
+ if is_causal:
99
+ causal_mask = torch.triu(torch.ones(L, S, dtype=torch.bool, device=query.device), diagonal=1)
100
+ scores = scores.masked_fill(causal_mask, float("-inf"))
101
+ if attention_mask is not None:
102
+ if attention_mask.dtype == torch.bool:
103
+ scores = scores.masked_fill(~attention_mask, float("-inf"))
104
+ else:
105
+ scores = scores + attention_mask
106
+
107
+ attn_weights = F.softmax(scores, dim=-1)
108
+
109
+ if dropout > 0.0:
110
+ attn_weights = F.dropout(attn_weights, p=dropout, training=True)
111
+
112
+ output = torch.matmul(attn_weights, value)
113
+ return output
114
+
115
+
116
+ # Grouped Query Attention
117
+ class GroupedQueryAttention(nn.Module):
118
+ def __init__(
119
+ self,
120
+ hidden_size: int,
121
+ num_heads: int,
122
+ num_key_value_heads: int,
123
+ head_dim: int,
124
+ max_seq_len: int,
125
+ ):
126
+ super().__init__()
127
+ self.hidden_size = hidden_size
128
+ self.num_heads = num_heads
129
+ self.num_key_value_heads = num_key_value_heads
130
+ self.head_dim = head_dim
131
+ self.max_seq_len = max_seq_len
132
+
133
+ self.q_proj = nn.Linear(hidden_size, head_dim * num_heads, bias=False)
134
+ self.k_proj = nn.Linear(hidden_size, head_dim * num_key_value_heads, bias=False)
135
+ self.v_proj = nn.Linear(hidden_size, head_dim * num_key_value_heads, bias=False)
136
+ self.out_proj = nn.Linear(num_heads * head_dim, hidden_size, bias=False)
137
+
138
+ self.rope = YaRNRoPE(
139
+ head_dim=head_dim,
140
+ original_max_seq_len=max_seq_len,
141
+ factor=16.0,
142
+ )
143
+
144
+ def forward(self, query, key, value):
145
+ B, L_q, _ = query.size()
146
+ _, L_kv, _ = key.size()
147
+
148
+ q = self.q_proj(query).view(B, L_q, self.num_heads, self.head_dim).transpose(1, 2)
149
+ k = self.k_proj(key).view(B, L_kv, self.num_key_value_heads, self.head_dim).transpose(1, 2)
150
+ v = self.v_proj(value).view(B, L_kv, self.num_key_value_heads, self.head_dim).transpose(1, 2)
151
+
152
+ q_embed = self.rope(q)
153
+ k_embed = self.rope(k)
154
+ q_embed, k_embed = q_embed.to(q.dtype), k_embed.to(k.dtype)
155
+
156
+ attn_output = scaled_dot_product_attention(
157
+ q_embed, k_embed, v,
158
+ attention_mask=torch.ones(L_q, L_kv, dtype=torch.bool, device=q_embed.device),
159
+ dropout=0.0,
160
+ is_causal=False,
161
+ enable_gqa=True,
162
+ )
163
+
164
+ context = attn_output.transpose(1, 2).contiguous().view(B, L_q, self.num_heads * self.head_dim)
165
+ output = self.out_proj(context)
166
+ return output
167
+
168
+
169
+ # Gated GELU Feed-Forward Network
170
+ class GEGLU(nn.Module):
171
+ def __init__(self, hidden_size: int, intermediate_size: Optional[int] = None):
172
+ super().__init__()
173
+ if intermediate_size is None:
174
+ intermediate_size = int(8 / 3 * hidden_size)
175
+ self.gate_proj = nn.Linear(hidden_size, intermediate_size, bias=False)
176
+ self.up_proj = nn.Linear(hidden_size, intermediate_size, bias=False)
177
+ self.down_proj = nn.Linear(intermediate_size, hidden_size, bias=False)
178
+
179
+ def forward(self, x):
180
+ gate = F.gelu(self.gate_proj(x))
181
+ value = self.up_proj(x)
182
+ hidden = gate * value
183
+ return self.down_proj(hidden)
184
+
185
+
186
+ # Transformer Decoder Layer
187
+ class TransformerDecoderLayer(nn.Module):
188
+ def __init__(
189
+ self,
190
+ hidden_size: int,
191
+ num_heads: int,
192
+ num_key_value_heads: int,
193
+ intermediate_size: int,
194
+ head_dim: int,
195
+ max_seq_len: int,
196
+ dropout: float,
197
+ ):
198
+ super().__init__()
199
+ self.self_attn = GroupedQueryAttention(
200
+ hidden_size, num_heads, num_key_value_heads, head_dim, max_seq_len
201
+ )
202
+ self.ffn = GEGLU(hidden_size, intermediate_size)
203
+ self.input_layernorm = nn.RMSNorm(hidden_size)
204
+ self.post_attention_layernorm = nn.RMSNorm(hidden_size)
205
+ self.dropout = nn.Dropout(dropout)
206
+
207
+ def forward(self, hidden_states):
208
+ residual = hidden_states
209
+ hidden_states = self.input_layernorm(hidden_states)
210
+ attn_output = self.dropout(self.self_attn(hidden_states, hidden_states, hidden_states))
211
+ hidden_states = residual + attn_output
212
+
213
+ residual = hidden_states
214
+ hidden_states = self.post_attention_layernorm(hidden_states)
215
+ ffn_output = self.dropout(self.ffn(hidden_states))
216
+ hidden_states = residual + ffn_output
217
+
218
+ return hidden_states
219
+
220
+
221
+ # Decoder with Dense Layer Connections
222
+ class TransformerDecoder(nn.Module):
223
+ def __init__(
224
+ self,
225
+ hidden_size: int,
226
+ num_heads: int,
227
+ num_key_value_heads: int,
228
+ intermediate_size: int,
229
+ head_dim: int,
230
+ num_layers: int,
231
+ max_seq_len: int,
232
+ dropout: float,
233
+ ):
234
+ super().__init__()
235
+ self.num_layers = num_layers
236
+ self.layers = nn.ModuleList([
237
+ TransformerDecoderLayer(
238
+ hidden_size, num_heads, num_key_value_heads,
239
+ intermediate_size, head_dim, max_seq_len, dropout
240
+ )
241
+ for _ in range(num_layers)
242
+ ])
243
+
244
+ mask = torch.tril(torch.ones(num_layers, num_layers), diagonal=-1)
245
+ self.register_buffer("layer_weight_mask", mask)
246
+ self.layer_raw_weights = nn.Parameter(torch.randn(num_layers, num_layers) / 10)
247
+
248
+ def forward(self, hidden_states):
249
+ history = []
250
+ for idx_layer, layer in enumerate(self.layers):
251
+ layer_output = layer(hidden_states)
252
+
253
+ if history:
254
+ raw_weights = self.layer_raw_weights[idx_layer, :idx_layer]
255
+ masked_weights = raw_weights * self.layer_weight_mask[idx_layer, :idx_layer]
256
+ weights = F.softmax(masked_weights, dim=0)
257
+ hist_stack = torch.stack(history, dim=0)
258
+ residual = torch.einsum("lbtd,l->btd", hist_stack, weights)
259
+ hidden_states = layer_output + residual
260
+ else:
261
+ hidden_states = layer_output
262
+
263
+ history.append(hidden_states)
264
+
265
+ return hidden_states
266
+
267
+
268
+ # Classifier
269
+ class Classifier(nn.Module):
270
+ def __init__(
271
+ self,
272
+ hidden_size: int,
273
+ num_heads: int,
274
+ num_key_value_heads: int,
275
+ intermediate_size: int,
276
+ head_dim: int,
277
+ vocab_size: int,
278
+ num_layers: int,
279
+ max_seq_len: int,
280
+ dropout: float,
281
+ ):
282
+ super().__init__()
283
+ self.token_embedding = nn.Embedding(vocab_size, hidden_size)
284
+ self.decoder = TransformerDecoder(
285
+ hidden_size, num_heads, num_key_value_heads,
286
+ intermediate_size, head_dim, num_layers, max_seq_len, dropout
287
+ )
288
+ self.final_layernorm = nn.RMSNorm(hidden_size)
289
+ self.lm_head = nn.Linear(hidden_size, 6, bias=False)
290
+
291
+ def forward(self, input_ids):
292
+ hidden_states = self.token_embedding(input_ids)
293
+ hidden_states = self.decoder(hidden_states)
294
+ hidden_states = self.final_layernorm(hidden_states)
295
+ logits = self.lm_head(hidden_states).mean(-2)
296
+ return logits
new_model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9b737b4e7f0ac6d998b83e1d8892e62c1b9aa0124d2defbfd411a35fc9d4e4c3
3
+ size 19291522
sample/test.jsonl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7b6448daf8d958391af38e0990d7e666d041a20641c521fbaffae5bc508ee2e9
3
+ size 140796983
save/file_0.jsonl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7e913e0af7f61bcd45bc5974373ffea1cca290a424b2ccb5b4821026779a34b4
3
+ size 44432404
tokenizer.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Union, Optional, Dict, Any
2
+ from transformers import AutoTokenizer
3
+
4
+ import os
5
+ os.environ["TOKENIZERS_PARALLELISM"] = "false"
6
+
7
+ class Tokenizer:
8
+ """
9
+ 轻量级封装,统一接口:
10
+ encode -> input_ids, attention_mask
11
+ decode -> 字符串
12
+ 其余常用属性直接暴露。
13
+ """
14
+
15
+ def __init__(self, model_name: str, trust_remote_code: bool = True):
16
+ self.tokenizer = AutoTokenizer.from_pretrained(
17
+ model_name,
18
+ trust_remote_code=trust_remote_code
19
+ )
20
+ # self.tokenizer.chat_template = """{% for message in messages %}{% if message['role'] == 'system' %}{% if message['content'] == '' %}<system> {{ '你是一个人工智能助手' }} </system>{% else %}<system> {{ message['content'] }} </system>{% endif %}{% elif message['role'] == 'user' %}<user> {{ message['content'] }} </user>{% elif message['role'] == 'assistant' %}<assistant>{{ message['content'] }}</assistant>{% endif %}{% endfor %}"""
21
+ self.tokenizer.chat_template = """{% for message in messages %}{% if message['role'] == 'system' %}<system> {{ message['content'] }} </system>{% elif message['role'] == 'user' %}<user> {{ message['content'] }} </user>{% elif message['role'] == 'assistant' %}<assistant>{{ message['content'] }}</assistant>{% endif %}{% endfor %}"""
22
+ # 如果 pad_token 不存在,统一用 eos_token 代替
23
+ if self.tokenizer.pad_token is None:
24
+ self.tokenizer.pad_token = self.tokenizer.eos_token
25
+
26
+ def encode(
27
+ self,
28
+ text: Union[str, List[str]],
29
+ max_length: Optional[int] = None,
30
+ padding: Optional[str] = "do_not_pad",
31
+ truncation: bool = False,
32
+ return_tensors: Optional[str] = None,
33
+ add_special_tokens: bool = False,
34
+ ) -> Dict[str, Any]:
35
+ encoded = self.tokenizer(
36
+ text,
37
+ max_length=max_length,
38
+ padding=padding,
39
+ truncation=truncation,
40
+ return_tensors=return_tensors,
41
+ add_special_tokens=add_special_tokens
42
+ )
43
+ return encoded
44
+
45
+ def encode_chat(
46
+ self,
47
+ text: List[Dict[str, Any]],
48
+ ) -> Dict[str, Any]:
49
+ encoded = self.tokenizer.apply_chat_template(
50
+ text,
51
+ tokenize=False
52
+ )
53
+ return encoded
54
+
55
+ def decode(
56
+ self,
57
+ token_ids: Union[List[int], List[List[int]]],
58
+ skip_special_tokens: bool = False,
59
+ clean_up_tokenization_spaces: bool = False
60
+ ) -> Union[str, List[str]]:
61
+ if isinstance(token_ids[0], int): # 单条
62
+ return self.tokenizer.decode(
63
+ token_ids,
64
+ skip_special_tokens=skip_special_tokens,
65
+ clean_up_tokenization_spaces=clean_up_tokenization_spaces
66
+ )
67
+ # batch
68
+ return self.tokenizer.batch_decode(
69
+ token_ids,
70
+ skip_special_tokens=skip_special_tokens,
71
+ clean_up_tokenization_spaces=clean_up_tokenization_spaces
72
+ )
73
+
74
+ @property
75
+ def vocab_size(self) -> int:
76
+ return len(self.tokenizer)
77
+
78
+ @property
79
+ def pad_token_id(self) -> int:
80
+ return self.tokenizer.pad_token_id
81
+
82
+ @property
83
+ def eos_token_id(self) -> int:
84
+ return self.tokenizer.eos_token_id
85
+
86
+ @property
87
+ def bos_token_id(self) -> int:
88
+ return self.tokenizer.bos_token_id
89
+
90
+ @property
91
+ def unk_token_id(self) -> int:
92
+ return self.tokenizer.unk_token_id
93
+
94
+ # 兼容旧接口
95
+ def get_vocab_size(self) -> int:
96
+ return self.vocab_size
97
+
98
+ def get_eot_token(self) -> int:
99
+ """End-Of-Text token,与 GPT 系列保持一致命名。"""
100
+ return self.eos_token_id
101
+
102
+ if __name__ == '__main__':
103
+ tokenizer = Tokenizer("./llama2_tokenizer_32k")
104
+ print(tokenizer.get_eot_token())
105
+ encode = tokenizer.encode_chat([{"role": "system", "content": ""}, {"role": "user", "content": "请告诉我在中国古代的“四大发明”是什么?"}, {"role": "assistant", "content": "中国古代的“四大发明”是指造纸术、印刷术、火药和指南针。这四项发明对世界文明的发展产生了深远的影响:\n\n1. **造纸术**:据史书记载,东汉时期的蔡伦改进了造纸工艺,使得纸张的生产更加便捷、成本更低,质量也更加优良。这一发明极大地促进了文化的传播和保存。\n\n2. **印刷术**:中国古代的印刷术最早可以追溯到唐代的雕版印刷,到了宋代发展出了活字印刷技术。印刷术的发明极大地促进了知识的传播,降低了书籍的成本,对教育和文化的发展起到了重要的推动作用。\n\n3. **火药**:火药最初是在唐代被发现的,最初可能用于医疗或炼金术。到了宋代,人们开始将火药用于军事目的,发明了各种火器。火药的发明改变了战争的面貌,对世界军事技术的发展产生了重大影响。\n\n4. **指���针**:指南针最初在中国被用于风水测量,后来逐渐发展成为航海导航的重要工具。这一发明极大地促进了海上航行技术的发展,对于新航路的开辟和世界地理大发现起到了关键作用。\n\n这四项发明不仅在中国历史上占有重要地位,而且对全世界的科技进步和文明发展都产生了深远的影响。"}])
106
+ print(type(encode))
107
+ print("orin length", len(encode))
108
+ encode = tokenizer.encode(str(encode), max_length=None, truncation=True, padding="do_not_pad")
109
+ for token in encode['input_ids']:
110
+ print(tokenizer.decode([token]))
111
+ decode = tokenizer.decode([encode['input_ids']])
112
+ print("token lens: ", len(encode['input_ids']))
113
+ print("encode: ", encode)
114
+ print("att_mask: ", encode['attention_mask'])
115
+ print("decode: ", decode)
116
+ print("vocab_size", tokenizer.get_vocab_size())
117
+ print("eot", tokenizer.get_eot_token(), tokenizer.decode([tokenizer.get_eot_token()]))
118
+ print("eos", tokenizer.eos_token_id, tokenizer.decode([tokenizer.eos_token_id]))
119
+ print("unk", tokenizer.unk_token_id, tokenizer.decode([tokenizer.unk_token_id]))
120
+ print("pad", tokenizer.pad_token_id, tokenizer.decode([tokenizer.pad_token_id]))
121
+ print("bos", tokenizer.bos_token_id, tokenizer.decode([tokenizer.bos_token_id]))
122
+ for i in range(10):
123
+ print(i, tokenizer.decode([i]))
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+