ai 1.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ai/__init__.py ADDED
@@ -0,0 +1 @@
1
+ __version__ = '1.1.1'
ai/config.py ADDED
@@ -0,0 +1,122 @@
1
+ import os
2
+ import yaml
3
+ from configparser import ConfigParser
4
+
5
+
6
+ class AttrDict(dict):
7
+ def __init__(self, *args, **kwargs):
8
+ super(AttrDict, self).__init__(*args, **kwargs)
9
+ self.__dict__ = self
10
+
11
+
12
+ def get_yaml_config(filepath):
13
+ """使用 .yaml 文件配置
14
+ """
15
+ return AttrDict(yaml.load(open(filepath, 'r'), Loader=yaml.FullLoader))
16
+
17
+
18
+ def get_conf_config(filepath):
19
+ """使用 .conf 文件配置
20
+ """
21
+ conf = ConfigParser()
22
+ conf.read(filepath, encoding="UTF-8")
23
+ return conf
24
+
25
+
26
+ class Dict(dict):
27
+ """重写 dict, 支持 “.” 方式的属性调用
28
+ """
29
+ def __init__(self, *args, **kwargs):
30
+ super(Dict, self).__init__(*args, **kwargs)
31
+
32
+ def __getattr__(self, key):
33
+ try:
34
+ value = self[key]
35
+ if isinstance(value, dict):
36
+ value = Dict(value)
37
+ return value
38
+ except KeyError as k:
39
+ return None
40
+
41
+ def __setattr__(self, key, value):
42
+ if isinstance(value, dict):
43
+ value = Dict(value)
44
+ self[key] = value
45
+
46
+ def __delattr__(self, key):
47
+ try:
48
+ del self[key]
49
+ except KeyError as k:
50
+ return None
51
+
52
+ def __call__(self, key):
53
+ try:
54
+ return self[key]
55
+ except KeyError as k:
56
+ return None
57
+
58
+
59
+ class Config(object):
60
+ """支持链式调用的 Config
61
+ """
62
+ def __init__(self, filepath=None):
63
+ if filepath:
64
+ self.filepath = filepath
65
+ else:
66
+ cur_dir = os.path.split(os.path.realpath(__file__))[0]
67
+ self.filepath = os.path.join(cur_dir, "self.conf")
68
+ self.config = get_conf_config(self.filepath)
69
+ self.d = Dict()
70
+ for s in self.config.sections():
71
+ value = Dict()
72
+ for k in self.config.options(s):
73
+ value[k] = self.config.get(s, k)
74
+ self.d[s] = value
75
+
76
+ def add(self, section):
77
+ self.config.add_section(section)
78
+ self.d[section] = Dict()
79
+ with open(self.filepath, 'w', encoding="UTF-8") as f:
80
+ self.config.write(f)
81
+
82
+ def set(self, section, key, value):
83
+ self.config.set(section, key, value)
84
+ self.d[section][key] = value
85
+ with open(self.filepath, 'w', encoding="UTF-8") as f:
86
+ self.config.write(f)
87
+
88
+ def get(self, section, key):
89
+ return self.config.get(section, key, default=None)
90
+
91
+ def remove_section(self, section):
92
+ self.config.remove_section(section)
93
+ del self.d[section]
94
+ with open(self.filepath, 'w', encoding="UTF-8") as f:
95
+ self.config.write(f)
96
+
97
+ def remove_option(self, section, key):
98
+ self.config.remove_option(section, key)
99
+ del self.d[section][key]
100
+ with open(self.filepath, 'w', encoding="UTF-8") as f:
101
+ self.config.write(f)
102
+
103
+ def save(self):
104
+ for s in self.d:
105
+ if s not in self.config.sections():
106
+ self.add(s)
107
+ for k in self.d[s]:
108
+ try:
109
+ v = self.get(s, k)
110
+ except:
111
+ v = None
112
+ if self.d[s][k] != v:
113
+ self.set(s, k, self.d[s][k])
114
+
115
+ def __getattr__(self, name):
116
+ if name not in self.__dict__:
117
+ try:
118
+ return self.d[name]
119
+ except KeyError as k:
120
+ self.d[name] = Dict()
121
+ return self.d[name]
122
+ return self.__dict__[name]
ai/data/__init__.py ADDED
File without changes
ai/data/augment.py ADDED
@@ -0,0 +1,450 @@
1
+ import cv2
2
+ import math
3
+ import random
4
+ import numpy as np
5
+ from PIL import Image, ImageFilter
6
+
7
+
8
+ class WarpMLS:
9
+ def __init__(self, src, src_pts, dst_pts, dst_w, dst_h, trans_ratio=1.):
10
+ self.src = src
11
+ self.src_pts = src_pts
12
+ self.dst_pts = dst_pts
13
+ self.pt_count = len(self.dst_pts)
14
+ self.dst_w = dst_w
15
+ self.dst_h = dst_h
16
+ self.trans_ratio = trans_ratio
17
+ self.grid_size = 100
18
+ self.rdx = np.zeros((self.dst_h, self.dst_w))
19
+ self.rdy = np.zeros((self.dst_h, self.dst_w))
20
+
21
+ @staticmethod
22
+ def _bilinear_interp(x, y, v11, v12, v21, v22):
23
+ return (v11 * (1 - y) + v12 * y) * (1 - x) + (v21 * (1 - y) + v22 * y) * x
24
+
25
+ def generate(self):
26
+ self.calc_delta()
27
+ return self.gen_img()
28
+
29
+ def calc_delta(self):
30
+ w = np.zeros(self.pt_count, dtype=np.float32)
31
+
32
+ if self.pt_count < 2:
33
+ return
34
+
35
+ i = 0
36
+ while 1:
37
+ if self.dst_w <= i < self.dst_w + self.grid_size - 1:
38
+ i = self.dst_w - 1
39
+ elif i >= self.dst_w:
40
+ break
41
+
42
+ j = 0
43
+ while 1:
44
+ if self.dst_h <= j < self.dst_h + self.grid_size - 1:
45
+ j = self.dst_h - 1
46
+ elif j >= self.dst_h:
47
+ break
48
+
49
+ sw = 0
50
+ swp = np.zeros(2, dtype=np.float32)
51
+ swq = np.zeros(2, dtype=np.float32)
52
+ new_pt = np.zeros(2, dtype=np.float32)
53
+ cur_pt = np.array([i, j], dtype=np.float32)
54
+
55
+ k = 0
56
+ for k in range(self.pt_count):
57
+ if i == self.dst_pts[k][0] and j == self.dst_pts[k][1]:
58
+ break
59
+
60
+ w[k] = 1. / ((i - self.dst_pts[k][0]) * (i - self.dst_pts[k][0]) +
61
+ (j - self.dst_pts[k][1]) * (j - self.dst_pts[k][1]))
62
+
63
+ sw += w[k]
64
+ swp = swp + w[k] * np.array(self.dst_pts[k])
65
+ swq = swq + w[k] * np.array(self.src_pts[k])
66
+
67
+ if k == self.pt_count - 1:
68
+ pstar = 1 / sw * swp
69
+ qstar = 1 / sw * swq
70
+
71
+ miu_s = 0
72
+ for k in range(self.pt_count):
73
+ if i == self.dst_pts[k][0] and j == self.dst_pts[k][1]:
74
+ continue
75
+ pt_i = self.dst_pts[k] - pstar
76
+ miu_s += w[k] * np.sum(pt_i * pt_i)
77
+
78
+ cur_pt -= pstar
79
+ cur_pt_j = np.array([-cur_pt[1], cur_pt[0]])
80
+
81
+ for k in range(self.pt_count):
82
+ if i == self.dst_pts[k][0] and j == self.dst_pts[k][1]:
83
+ continue
84
+
85
+ pt_i = self.dst_pts[k] - pstar
86
+ pt_j = np.array([-pt_i[1], pt_i[0]])
87
+
88
+ tmp_pt = np.zeros(2, dtype=np.float32)
89
+ tmp_pt[0] = np.sum(pt_i * cur_pt) * self.src_pts[k][0] - \
90
+ np.sum(pt_j * cur_pt) * self.src_pts[k][1]
91
+ tmp_pt[1] = -np.sum(pt_i * cur_pt_j) * self.src_pts[k][0] + \
92
+ np.sum(pt_j * cur_pt_j) * self.src_pts[k][1]
93
+ tmp_pt *= (w[k] / miu_s)
94
+ new_pt += tmp_pt
95
+
96
+ new_pt += qstar
97
+ else:
98
+ new_pt = self.src_pts[k]
99
+
100
+ self.rdx[j, i] = new_pt[0] - i
101
+ self.rdy[j, i] = new_pt[1] - j
102
+
103
+ j += self.grid_size
104
+ i += self.grid_size
105
+
106
+ def gen_img(self):
107
+ src_h, src_w = self.src.shape[:2]
108
+ dst = np.zeros_like(self.src, dtype=np.float32)
109
+
110
+ for i in np.arange(0, self.dst_h, self.grid_size):
111
+ for j in np.arange(0, self.dst_w, self.grid_size):
112
+ ni = i + self.grid_size
113
+ nj = j + self.grid_size
114
+ w = h = self.grid_size
115
+ if ni >= self.dst_h:
116
+ ni = self.dst_h - 1
117
+ h = ni - i + 1
118
+ if nj >= self.dst_w:
119
+ nj = self.dst_w - 1
120
+ w = nj - j + 1
121
+
122
+ di = np.reshape(np.arange(h), (-1, 1))
123
+ dj = np.reshape(np.arange(w), (1, -1))
124
+ delta_x = self._bilinear_interp(di / h, dj / w,
125
+ self.rdx[i, j], self.rdx[i, nj],
126
+ self.rdx[ni, j], self.rdx[ni, nj])
127
+ delta_y = self._bilinear_interp(di / h, dj / w,
128
+ self.rdy[i, j], self.rdy[i, nj],
129
+ self.rdy[ni, j], self.rdy[ni, nj])
130
+ nx = j + dj + delta_x * self.trans_ratio
131
+ ny = i + di + delta_y * self.trans_ratio
132
+ nx = np.clip(nx, 0, src_w - 1)
133
+ ny = np.clip(ny, 0, src_h - 1)
134
+ nxi = np.array(np.floor(nx), dtype=np.int32)
135
+ nyi = np.array(np.floor(ny), dtype=np.int32)
136
+ nxi1 = np.array(np.ceil(nx), dtype=np.int32)
137
+ nyi1 = np.array(np.ceil(ny), dtype=np.int32)
138
+
139
+ if len(self.src.shape) == 3:
140
+ x = np.tile(np.expand_dims(ny - nyi, axis=-1), (1, 1, 3))
141
+ y = np.tile(np.expand_dims(nx - nxi, axis=-1), (1, 1, 3))
142
+ else:
143
+ x = ny - nyi
144
+ y = nx - nxi
145
+ dst[i:i + h, j:j + w] = self._bilinear_interp(
146
+ x,
147
+ y,
148
+ self.src[nyi, nxi],
149
+ self.src[nyi, nxi1],
150
+ self.src[nyi1, nxi],
151
+ self.src[nyi1, nxi1]
152
+ )
153
+ dst = np.clip(dst, 0, 255)
154
+ dst = np.array(dst, dtype=np.uint8)
155
+ return dst
156
+
157
+
158
+ def distort(src, segment=4):
159
+ img_h, img_w = src.shape[:2]
160
+ cut = img_w // segment
161
+ thresh = cut // 3
162
+ if thresh == 0:
163
+ return src
164
+
165
+ src_pts = list()
166
+ dst_pts = list()
167
+
168
+ src_pts.append([0, 0])
169
+ src_pts.append([img_w, 0])
170
+ src_pts.append([img_w, img_h])
171
+ src_pts.append([0, img_h])
172
+
173
+ dst_pts.append([np.random.randint(thresh), np.random.randint(thresh)])
174
+ dst_pts.append([img_w - np.random.randint(thresh), np.random.randint(thresh)])
175
+ dst_pts.append([img_w - np.random.randint(thresh), img_h - np.random.randint(thresh)])
176
+ dst_pts.append([np.random.randint(thresh), img_h - np.random.randint(thresh)])
177
+
178
+ half_thresh = thresh * 0.5
179
+
180
+ for cut_idx in np.arange(1, segment, 1):
181
+ src_pts.append([cut * cut_idx, 0])
182
+ src_pts.append([cut * cut_idx, img_h])
183
+ dst_pts.append([cut * cut_idx + np.random.randint(thresh) - half_thresh,
184
+ np.random.randint(thresh) - half_thresh])
185
+ dst_pts.append([cut * cut_idx + np.random.randint(thresh) - half_thresh,
186
+ img_h + np.random.randint(thresh) - half_thresh])
187
+
188
+ trans = WarpMLS(src, src_pts, dst_pts, img_w, img_h)
189
+ dst = trans.generate()
190
+
191
+ return dst
192
+
193
+
194
+ def stretch(src, segment=4):
195
+ img_h, img_w = src.shape[:2]
196
+
197
+ cut = img_w // segment
198
+ thresh = cut * 4 // 5
199
+ if thresh == 0:
200
+ return src
201
+
202
+ src_pts = list()
203
+ dst_pts = list()
204
+
205
+ src_pts.append([0, 0])
206
+ src_pts.append([img_w, 0])
207
+ src_pts.append([img_w, img_h])
208
+ src_pts.append([0, img_h])
209
+
210
+ dst_pts.append([0, 0])
211
+ dst_pts.append([img_w, 0])
212
+ dst_pts.append([img_w, img_h])
213
+ dst_pts.append([0, img_h])
214
+
215
+ half_thresh = thresh * 0.5
216
+
217
+ for cut_idx in np.arange(1, segment, 1):
218
+ move = np.random.randint(thresh) - half_thresh
219
+ src_pts.append([cut * cut_idx, 0])
220
+ src_pts.append([cut * cut_idx, img_h])
221
+ dst_pts.append([cut * cut_idx + move, 0])
222
+ dst_pts.append([cut * cut_idx + move, img_h])
223
+
224
+ trans = WarpMLS(src, src_pts, dst_pts, img_w, img_h)
225
+ dst = trans.generate()
226
+
227
+ return dst
228
+
229
+
230
+ def perspective(src):
231
+ img_h, img_w = src.shape[:2]
232
+
233
+ thresh = img_h // 2
234
+ if thresh == 0:
235
+ return src
236
+
237
+ src_pts = list()
238
+ dst_pts = list()
239
+
240
+ src_pts.append([0, 0])
241
+ src_pts.append([img_w, 0])
242
+ src_pts.append([img_w, img_h])
243
+ src_pts.append([0, img_h])
244
+
245
+ dst_pts.append([0, np.random.randint(thresh)])
246
+ dst_pts.append([img_w, np.random.randint(thresh)])
247
+ dst_pts.append([img_w, img_h - np.random.randint(thresh)])
248
+ dst_pts.append([0, img_h - np.random.randint(thresh)])
249
+
250
+ trans = WarpMLS(src, src_pts, dst_pts, img_w, img_h)
251
+ dst = trans.generate()
252
+
253
+ return dst
254
+
255
+
256
+ def gridmask(src, d1=4, d2=16, rotate=1, ratio=0.5, mode=0):
257
+ h, w, c = src.shape
258
+ hh = math.ceil((math.sqrt(h*h + w*w)))
259
+ d = np.random.randint(d1, d2)
260
+ l = math.ceil(d * ratio)
261
+
262
+ mask = np.ones((hh, hh), np.float32)
263
+ st_h = np.random.randint(d)
264
+ st_w = np.random.randint(d)
265
+ for i in range(-1, hh//d+1):
266
+ s = d*i + st_h
267
+ t = s + l
268
+ s = max(min(s, hh), 0)
269
+ t = max(min(t, hh), 0)
270
+ mask[s:t,:] *= 0
271
+ for i in range(-1, hh//d+1):
272
+ s = d*i + st_w
273
+ t = s + l
274
+ s = max(min(s, hh), 0)
275
+ t = max(min(t, hh), 0)
276
+ mask[:,s:t] *= 0
277
+ r = np.random.randint(rotate)
278
+ mask = Image.fromarray(np.uint8(mask))
279
+ mask = mask.rotate(r)
280
+ mask = np.asarray(mask)
281
+ mask = mask[(hh-h)//2:(hh-h)//2+h, (hh-w)//2:(hh-w)//2+w]
282
+
283
+ if mode == 1:
284
+ mask = 1 - mask
285
+
286
+ if c == 3:
287
+ mask = cv2.merge([mask, mask, mask])
288
+
289
+ dst = src * mask
290
+ return np.uint8(dst)
291
+
292
+
293
+ class RandomDistort(object):
294
+ def __init__(self, p=0.1):
295
+ self.p = p
296
+
297
+ def __call__(self, img):
298
+ if random.random() > self.p:
299
+ return img
300
+ img = np.array(img)
301
+ img = distort(img)
302
+ return Image.fromarray(np.uint8(img))
303
+
304
+ def __repr__(self):
305
+ return self.__class__.__name__ + '()'
306
+
307
+
308
+ class RandomStretch(object):
309
+ def __init__(self, p=0.1):
310
+ self.p = p
311
+
312
+ def __call__(self, img):
313
+ if random.random() > self.p:
314
+ return img
315
+ img = np.array(img)
316
+ img = stretch(img)
317
+ return Image.fromarray(np.uint8(img))
318
+
319
+ def __repr__(self):
320
+ return self.__class__.__name__ + '()'
321
+
322
+
323
+ class RandomPerspective(object):
324
+ def __init__(self, p=0.1):
325
+ self.p = p
326
+
327
+ def __call__(self, img):
328
+ if random.random() > self.p:
329
+ return img
330
+ img = np.array(img)
331
+ img = perspective(img)
332
+ return Image.fromarray(np.uint8(img))
333
+
334
+ def __repr__(self):
335
+ return self.__class__.__name__ + '()'
336
+
337
+
338
+ class RandomGridMask(object):
339
+ def __init__(self, p=0.5):
340
+ self.p = p
341
+
342
+ def __call__(self, img):
343
+ if random.random() > self.p:
344
+ return img
345
+ img = np.array(img)
346
+ img = gridmask(img)
347
+ return Image.fromarray(np.uint8(img))
348
+
349
+ def __repr__(self):
350
+ return self.__class__.__name__ + '()'
351
+
352
+
353
+ class AddPepperNoise(object):
354
+ """增加椒盐噪声
355
+ Args:
356
+ snr (float): Signal Noise Rate
357
+ p (float): 概率值,依概率执行该操作
358
+ """
359
+ def __init__(self, snr, p=0.5):
360
+ assert isinstance(snr, float) or (isinstance(p, float))
361
+ self.snr = snr
362
+ self.p = p
363
+
364
+ def __call__(self, img):
365
+ if random.random() > self.p:
366
+ return img
367
+ img = np.array(img)
368
+ h, w, c = img.shape
369
+ signal_pct = self.snr
370
+ noise_pct = (1 - self.snr)
371
+ mask = np.random.choice((0, 1, 2), size=(h, w, 1), p=[signal_pct, noise_pct/2., noise_pct/2.])
372
+ mask = np.repeat(mask, c, axis=2)
373
+ img[mask == 1] = 255 # 盐噪声
374
+ img[mask == 2] = 0 # 椒噪声
375
+ return Image.fromarray(np.uint8(img))
376
+
377
+ def __repr__(self):
378
+ return self.__class__.__name__ + '()'
379
+
380
+
381
+ class GaussianBlur(object):
382
+ """Gaussian blur augmentation in SimCLR https://arxiv.org/abs/2002.05709"""
383
+
384
+ def __init__(self, sigma=[.1, 2.], p=0.5):
385
+ self.sigma = sigma
386
+ self.p = p
387
+
388
+ def __call__(self, img):
389
+ if random.random() > self.p:
390
+ return img
391
+ sigma = random.uniform(self.sigma[0], self.sigma[1])
392
+ img = img.filter(ImageFilter.GaussianBlur(radius=sigma))
393
+ return img
394
+
395
+ def __repr__(self):
396
+ return self.__class__.__name__ + '()'
397
+
398
+
399
+ class RandomErasing(object):
400
+ """
401
+ https://github.com/zhunzhong07/Random-Erasing
402
+ Args:
403
+ p: The prob that the operation will be performed.
404
+ sl: min erasing area
405
+ sh: max erasing area
406
+ r1: min aspect ratio
407
+ mean: erasing value
408
+ """
409
+ def __init__(self, p=0.5, sl=0.01, sh=0.1, r1=0.2, max_attempts=10, aspect_ratio=None, mean=[0.4914, 0.4822, 0.4465]):
410
+ self.p = p
411
+ self.sl = sl
412
+ self.sh = sh
413
+ self.r1 = r1
414
+ self.mean = mean
415
+ self.max_attempts = max_attempts
416
+ self.aspect_ratio = aspect_ratio
417
+
418
+ def __call__(self, img):
419
+ if random.random() > self.p:
420
+ return img
421
+ img = np.array(img)
422
+ h, w, c = img.shape
423
+
424
+ for attempt in range(self.max_attempts):
425
+ area = h * w
426
+
427
+ target_area = random.uniform(self.sl, self.sh) * area
428
+ if self.aspect_ratio is None:
429
+ aspect_ratio = random.uniform(self.r1, 1/self.r1)
430
+ else:
431
+ aspect_ratio = self.aspect_ratio
432
+
433
+ eh = int(round(math.sqrt(target_area * aspect_ratio)))
434
+ ew = int(round(math.sqrt(target_area / aspect_ratio)))
435
+
436
+ if ew < w and eh < h:
437
+ x1 = random.randint(0, h - eh)
438
+ y1 = random.randint(0, w - ew)
439
+ if c == 3:
440
+ img[x1:x1+eh, y1:y1+ew, 0] = self.mean[0]
441
+ img[x1:x1+eh, y1:y1+ew, 1] = self.mean[1]
442
+ img[x1:x1+eh, y1:y1+ew, 2] = self.mean[2]
443
+ else:
444
+ img[x1:x1+eh, y1:y1+ew, 0] = self.mean[0]
445
+ return Image.fromarray(np.uint8(img))
446
+
447
+ return Image.fromarray(np.uint8(img))
448
+
449
+ def __repr__(self):
450
+ return self.__class__.__name__ + '()'
ai/llm/__init__.py ADDED
File without changes
ai/llm/postprocess.py ADDED
@@ -0,0 +1,125 @@
1
+ def get_csv_from_llm(res):
2
+ if '<answer>' in res:
3
+ start = res.find('<answer>')
4
+ if start != -1:
5
+ res = res[start+len('<answer>'):]
6
+ end = res.find('</answer>')
7
+ if end != -1:
8
+ res = res[:end]
9
+
10
+ res = res.strip()
11
+ res = res.replace('\n\n', '\n')
12
+ start_tag, end_tag = '```csv', '```'
13
+ left = res.rfind(start_tag)
14
+ if left == -1:
15
+ start_tag = '```'
16
+ left = res.rfind('```')
17
+ right = res.rfind(end_tag)
18
+ if left != -1 and right != -1 and right > left:
19
+ res = res[left+len(start_tag):right].strip()
20
+ else:
21
+ res = res.strip('`')
22
+
23
+ return res
24
+
25
+
26
+ def get_list_from_llm(res):
27
+ if '<answer>' in res:
28
+ start = res.find('<answer>')
29
+ if start != -1:
30
+ res = res[start+len('<answer>'):]
31
+ end = res.find('</answer>')
32
+ if end != -1:
33
+ res = res[:end]
34
+
35
+ res = res.strip()
36
+ res = res.replace('\n\n', '\n')
37
+ res = res.replace('",', '",')
38
+
39
+ if '"' not in res and "'" not in res:
40
+ res = res.strip('[]')
41
+ res = res.replace(';', ';')
42
+ tmp = res.split(';')
43
+ res = '[' + ','.join([f'"{t}"' for t in tmp]) + ']'
44
+
45
+ start_tag, end_tag = '```python', '```'
46
+ left = res.find(start_tag)
47
+ if left == -1:
48
+ start_tag = '```'
49
+ left = res.find('```')
50
+ right = res.rfind(end_tag)
51
+ if left != -1 and right != -1 and right > left:
52
+ res = res[left+len(start_tag):right].strip()
53
+ elif left != -1:
54
+ res = res[left+len(start_tag):].strip()
55
+ else:
56
+ res = res.strip('`')
57
+
58
+ left = res.find('[')
59
+ if left != -1:
60
+ res = res[left:]
61
+ else:
62
+ res = '[' + res
63
+
64
+ if not res.startswith('['):
65
+ res = '[' + res
66
+ if not res.endswith(']'):
67
+ if res.endswith(','):
68
+ res = res.strip(',')
69
+ if res.endswith(',"'):
70
+ res = res[:-2]
71
+ if not res.endswith('"'):
72
+ res += '"'
73
+ res += ']'
74
+ try:
75
+ data = eval(res)
76
+ except:
77
+ print('Error: get_list_from_llm')
78
+ print('res:', res)
79
+ data = []
80
+
81
+ return data
82
+
83
+
84
+ def get_json_from_llm(res):
85
+ if '<answer>' in res:
86
+ start = res.find('<answer>')
87
+ if start != -1:
88
+ res = res[start+len('<answer>'):]
89
+ end = res.find('</answer>')
90
+ if end != -1:
91
+ res = res[:end]
92
+
93
+ res = res.strip()
94
+ res = res.replace('\\\"', '"').replace('\\n', '\n')
95
+ res = res.replace('\n\n', '\n').replace('\n', '').replace(' ', '')
96
+ res = res.replace('",', '",').replace('""', '","')
97
+ res = res.replace('}{', '},{')
98
+
99
+ start_tag, end_tag = '```json', '```'
100
+ left = res.find(start_tag)
101
+ if left == -1:
102
+ start_tag = '```'
103
+ left = res.find(start_tag)
104
+ right = res.rfind(end_tag)
105
+ if left != -1 and right != -1 and right > left:
106
+ res = res[left+len(start_tag):right].strip()
107
+ elif left != -1:
108
+ res = res[left+len(start_tag):].strip()
109
+ else:
110
+ res = res.strip('`')
111
+
112
+ if '``````json' in res:
113
+ tmp = res.split('``````json')
114
+ res = '[' + ','.join(tmp) + ']'
115
+
116
+ res = res.replace('"""', '"')
117
+
118
+ try:
119
+ data = eval(res)
120
+ except:
121
+ print('Error: get_json_from_llm')
122
+ print('res:', res)
123
+ data = {}
124
+
125
+ return data
ai/optim/__init__.py ADDED
@@ -0,0 +1,472 @@
1
+ import math
2
+ import numpy as np
3
+ import torch
4
+ from torch.optim import Optimizer
5
+ from collections import defaultdict
6
+
7
+
8
+ class AdamGC(Optimizer):
9
+ r"""Implements AdamGC algorithm with Gradient Centralization.
10
+
11
+ It has been proposed in `Adam: A Method for Stochastic Optimization`_.
12
+
13
+ Arguments:
14
+ params (iterable): iterable of parameters to optimize or dicts defining
15
+ parameter groups
16
+ lr (float, optional): learning rate (default: 1e-3)
17
+ betas (Tuple[float, float], optional): coefficients used for computing
18
+ running averages of gradient and its square (default: (0.9, 0.999))
19
+ eps (float, optional): term added to the denominator to improve
20
+ numerical stability (default: 1e-8)
21
+ weight_decay (float, optional): weight decay (L2 penalty) (default: 0)
22
+ amsgrad (boolean, optional): whether to use the AMSGrad variant of this
23
+ algorithm from the paper `On the Convergence of Adam and Beyond`_
24
+ (default: False)
25
+
26
+ .. _Adam\: A Method for Stochastic Optimization:
27
+ https://arxiv.org/abs/1412.6980
28
+ .. _On the Convergence of Adam and Beyond:
29
+ https://openreview.net/forum?id=ryQu7f-RZ
30
+ """
31
+
32
+ def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,
33
+ weight_decay=0, amsgrad=False, correct_bias=False):
34
+ if not 0.0 <= lr:
35
+ raise ValueError("Invalid learning rate: {}".format(lr))
36
+ if not 0.0 <= eps:
37
+ raise ValueError("Invalid epsilon value: {}".format(eps))
38
+ if not 0.0 <= betas[0] < 1.0:
39
+ raise ValueError("Invalid beta parameter at index 0: {}".format(betas[0]))
40
+ if not 0.0 <= betas[1] < 1.0:
41
+ raise ValueError("Invalid beta parameter at index 1: {}".format(betas[1]))
42
+ defaults = dict(lr=lr, betas=betas, eps=eps, correct_bias=correct_bias,
43
+ weight_decay=weight_decay, amsgrad=amsgrad)
44
+ super(AdamGC, self).__init__(params, defaults)
45
+
46
+ def __setstate__(self, state):
47
+ super(AdamGC, self).__setstate__(state)
48
+ for group in self.param_groups:
49
+ group.setdefault('amsgrad', False)
50
+
51
+ def step(self, closure=None):
52
+ """Performs a single optimization step.
53
+
54
+ Arguments:
55
+ closure (callable, optional): A closure that reevaluates the model
56
+ and returns the loss.
57
+ """
58
+ loss = None
59
+ if closure is not None:
60
+ loss = closure()
61
+
62
+ for group in self.param_groups:
63
+ for p in group['params']:
64
+ if p.grad is None:
65
+ continue
66
+ grad = p.grad.data
67
+ if grad.is_sparse:
68
+ raise RuntimeError('Adam does not support sparse gradients, please consider SparseAdam instead')
69
+ amsgrad = group['amsgrad']
70
+
71
+ state = self.state[p]
72
+
73
+ # State initialization
74
+ if len(state) == 0:
75
+ state['step'] = 0
76
+ # Exponential moving average of gradient values
77
+ state['exp_avg'] = torch.zeros_like(p.data)
78
+ # Exponential moving average of squared gradient values
79
+ state['exp_avg_sq'] = torch.zeros_like(p.data)
80
+ if amsgrad:
81
+ # Maintains max of all exp. moving avg. of sq. grad. values
82
+ state['max_exp_avg_sq'] = torch.zeros_like(p.data)
83
+
84
+ exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']
85
+ if amsgrad:
86
+ max_exp_avg_sq = state['max_exp_avg_sq']
87
+ beta1, beta2 = group['betas']
88
+
89
+ state['step'] += 1
90
+
91
+ if group['weight_decay'] > 0:
92
+ grad.add_(group['weight_decay'], p.data)
93
+
94
+ # GC operation for Conv layers and FC layers
95
+ length = len(list(p.data.size()))
96
+ if length > 1:
97
+ grad.add_(-grad.mean(dim=tuple(range(1, length)), keepdim=True))
98
+
99
+ # Decay the first and second moment running average coefficient
100
+ exp_avg.mul_(beta1).add_(1 - beta1, grad)
101
+ exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad)
102
+
103
+ step_size = group["lr"]
104
+ if group["correct_bias"]: # No bias correction for Bert
105
+ bias_correction1 = 1.0 - beta1 ** state["step"]
106
+ bias_correction2 = 1.0 - beta2 ** state["step"]
107
+ step_size = step_size * math.sqrt(bias_correction2) / bias_correction1
108
+
109
+ if amsgrad:
110
+ # Maintains the maximum of all 2nd moment running avg. till now
111
+ torch.max(max_exp_avg_sq, exp_avg_sq, out=max_exp_avg_sq)
112
+ # Use the max. for normalizing running avg. of gradient
113
+ denom = max_exp_avg_sq.sqrt().add_(group['eps'])
114
+ else:
115
+ denom = exp_avg_sq.sqrt().add_(group['eps'])
116
+
117
+ p.data.addcdiv_(-step_size, exp_avg, denom)
118
+
119
+ return loss
120
+
121
+
122
+ class AdamW(Optimizer):
123
+ r"""Implements AdamW algorithm.
124
+ It has been proposed in `Adam: A Method for Stochastic Optimization`_.
125
+ Arguments:
126
+ params (iterable): iterable of parameters to optimize or dicts defining
127
+ parameter groups
128
+ lr (float, optional): learning rate (default: 1e-3)
129
+ betas (Tuple[float, float], optional): coefficients used for computing
130
+ running averages of gradient and its square (default: (0.9, 0.999))
131
+ eps (float, optional): term added to the denominator to improve
132
+ numerical stability (default: 1e-8)
133
+ weight_decay (float, optional): weight decay (L2 penalty) (default: 0)
134
+ amsgrad (boolean, optional): whether to use the AMSGrad variant of this
135
+ algorithm from the paper `On the Convergence of Adam and Beyond`_
136
+ .. _Adam\: A Method for Stochastic Optimization:
137
+ https://arxiv.org/abs/1412.6980
138
+ .. _On the Convergence of Adam and Beyond:
139
+ https://openreview.net/forum?id=ryQu7f-RZ
140
+ """
141
+
142
+ def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,
143
+ weight_decay=0, amsgrad=False, correct_bias=False):
144
+ if not 0.0 <= lr:
145
+ raise ValueError("Invalid learning rate: {}".format(lr))
146
+ if not 0.0 <= eps:
147
+ raise ValueError("Invalid epsilon value: {}".format(eps))
148
+ if not 0.0 <= betas[0] < 1.0:
149
+ raise ValueError("Invalid beta parameter at index 0: {}".format(betas[0]))
150
+ if not 0.0 <= betas[1] < 1.0:
151
+ raise ValueError("Invalid beta parameter at index 1: {}".format(betas[1]))
152
+ defaults = dict(lr=lr, betas=betas, eps=eps, correct_bias=correct_bias,
153
+ weight_decay=weight_decay, amsgrad=amsgrad)
154
+ super(AdamW, self).__init__(params, defaults)
155
+
156
+ def __setstate__(self, state):
157
+ super(AdamW, self).__setstate__(state)
158
+ for group in self.param_groups:
159
+ group.setdefault('amsgrad', False)
160
+
161
+ def step(self, closure=None):
162
+ """Performs a single optimization step.
163
+ Arguments:
164
+ closure (callable, optional): A closure that reevaluates the model
165
+ and returns the loss.
166
+ """
167
+ loss = None
168
+ if closure is not None:
169
+ loss = closure()
170
+
171
+ for group in self.param_groups:
172
+ for p in group['params']:
173
+ if p.grad is None:
174
+ continue
175
+ grad = p.grad.data
176
+ if grad.is_sparse:
177
+ raise RuntimeError('Adam does not support sparse gradients, please consider SparseAdam instead')
178
+ amsgrad = group['amsgrad']
179
+
180
+ state = self.state[p]
181
+
182
+ # State initialization
183
+ if len(state) == 0:
184
+ state['step'] = 0
185
+ # Exponential moving average of gradient values
186
+ state['exp_avg'] = torch.zeros_like(p.data)
187
+ # Exponential moving average of squared gradient values
188
+ state['exp_avg_sq'] = torch.zeros_like(p.data)
189
+ if amsgrad:
190
+ # Maintains max of all exp. moving avg. of sq. grad. values
191
+ state['max_exp_avg_sq'] = torch.zeros_like(p.data)
192
+
193
+ exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']
194
+ if amsgrad:
195
+ max_exp_avg_sq = state['max_exp_avg_sq']
196
+ beta1, beta2 = group['betas']
197
+
198
+ state['step'] += 1
199
+
200
+ if group['weight_decay'] > 0:
201
+ grad.add_(group['weight_decay'], p.data)
202
+
203
+ # Decay the first and second moment running average coefficient
204
+ exp_avg.mul_(beta1).add_(1 - beta1, grad)
205
+ exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad)
206
+
207
+ step_size = group["lr"]
208
+ if group["correct_bias"]: # No bias correction for Bert
209
+ bias_correction1 = 1.0 - beta1 ** state["step"]
210
+ bias_correction2 = 1.0 - beta2 ** state["step"]
211
+ step_size = step_size * math.sqrt(bias_correction2) / bias_correction1
212
+
213
+ if amsgrad:
214
+ # Maintains the maximum of all 2nd moment running avg. till now
215
+ torch.max(max_exp_avg_sq, exp_avg_sq, out=max_exp_avg_sq)
216
+ # Use the max. for normalizing running avg. of gradient
217
+ denom = max_exp_avg_sq.sqrt().add_(group['eps'])
218
+ else:
219
+ denom = exp_avg_sq.sqrt().add_(group['eps'])
220
+
221
+ # p.data.addcdiv_(-step_size, exp_avg, denom)
222
+ p.data.add_(-step_size, torch.mul(p.data, group['weight_decay']).addcdiv_(1, exp_avg, denom) )
223
+
224
+ return loss
225
+
226
+
227
+ class AdamWGC(Optimizer):
228
+ r"""Implements AdamWGC algorithm with Gradient Centralization.
229
+ It has been proposed in `Adam: A Method for Stochastic Optimization`_.
230
+ Arguments:
231
+ params (iterable): iterable of parameters to optimize or dicts defining
232
+ parameter groups
233
+ lr (float, optional): learning rate (default: 1e-3)
234
+ betas (Tuple[float, float], optional): coefficients used for computing
235
+ running averages of gradient and its square (default: (0.9, 0.999))
236
+ eps (float, optional): term added to the denominator to improve
237
+ numerical stability (default: 1e-8)
238
+ weight_decay (float, optional): weight decay (L2 penalty) (default: 0)
239
+ amsgrad (boolean, optional): whether to use the AMSGrad variant of this
240
+ algorithm from the paper `On the Convergence of Adam and Beyond`_
241
+ .. _Adam\: A Method for Stochastic Optimization:
242
+ https://arxiv.org/abs/1412.6980
243
+ .. _On the Convergence of Adam and Beyond:
244
+ https://openreview.net/forum?id=ryQu7f-RZ
245
+ """
246
+
247
+ def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,
248
+ weight_decay=0, amsgrad=False, correct_bias=False):
249
+ if not 0.0 <= lr:
250
+ raise ValueError("Invalid learning rate: {}".format(lr))
251
+ if not 0.0 <= eps:
252
+ raise ValueError("Invalid epsilon value: {}".format(eps))
253
+ if not 0.0 <= betas[0] < 1.0:
254
+ raise ValueError("Invalid beta parameter at index 0: {}".format(betas[0]))
255
+ if not 0.0 <= betas[1] < 1.0:
256
+ raise ValueError("Invalid beta parameter at index 1: {}".format(betas[1]))
257
+ defaults = dict(lr=lr, betas=betas, eps=eps, correct_bias=correct_bias,
258
+ weight_decay=weight_decay, amsgrad=amsgrad)
259
+ super(AdamWGC, self).__init__(params, defaults)
260
+
261
+ def __setstate__(self, state):
262
+ super(AdamWGC, self).__setstate__(state)
263
+ for group in self.param_groups:
264
+ group.setdefault('amsgrad', False)
265
+
266
+ def step(self, closure=None):
267
+ """Performs a single optimization step.
268
+ Arguments:
269
+ closure (callable, optional): A closure that reevaluates the model
270
+ and returns the loss.
271
+ """
272
+ loss = None
273
+ if closure is not None:
274
+ loss = closure()
275
+
276
+ for group in self.param_groups:
277
+ for p in group['params']:
278
+ if p.grad is None:
279
+ continue
280
+ grad = p.grad.data
281
+ if grad.is_sparse:
282
+ raise RuntimeError('Adam does not support sparse gradients, please consider SparseAdam instead')
283
+ amsgrad = group['amsgrad']
284
+
285
+ state = self.state[p]
286
+
287
+ # State initialization
288
+ if len(state) == 0:
289
+ state['step'] = 0
290
+ # Exponential moving average of gradient values
291
+ state['exp_avg'] = torch.zeros_like(p.data)
292
+ # Exponential moving average of squared gradient values
293
+ state['exp_avg_sq'] = torch.zeros_like(p.data)
294
+ if amsgrad:
295
+ # Maintains max of all exp. moving avg. of sq. grad. values
296
+ state['max_exp_avg_sq'] = torch.zeros_like(p.data)
297
+
298
+ exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']
299
+ if amsgrad:
300
+ max_exp_avg_sq = state['max_exp_avg_sq']
301
+ beta1, beta2 = group['betas']
302
+
303
+ # GC operation for Conv layers and FC layers
304
+ length = len(list(p.data.size()))
305
+ if length > 1:
306
+ grad.add_(-grad.mean(dim=tuple(range(1, length)), keepdim=True))
307
+
308
+ state['step'] += 1
309
+
310
+ if group['weight_decay'] > 0:
311
+ grad.add_(group['weight_decay'], p.data)
312
+
313
+ # Decay the first and second moment running average coefficient
314
+ exp_avg.mul_(beta1).add_(1 - beta1, grad)
315
+ exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad)
316
+ if amsgrad:
317
+ # Maintains the maximum of all 2nd moment running avg. till now
318
+ torch.max(max_exp_avg_sq, exp_avg_sq, out=max_exp_avg_sq)
319
+ # Use the max. for normalizing running avg. of gradient
320
+ denom = max_exp_avg_sq.sqrt().add_(group['eps'])
321
+ else:
322
+ denom = exp_avg_sq.sqrt().add_(group['eps'])
323
+
324
+ step_size = group["lr"]
325
+ if group["correct_bias"]: # No bias correction for Bert
326
+ bias_correction1 = 1.0 - beta1 ** state["step"]
327
+ bias_correction2 = 1.0 - beta2 ** state["step"]
328
+ step_size = step_size * math.sqrt(bias_correction2) / bias_correction1
329
+
330
+ # p.data.addcdiv_(-step_size, exp_avg, denom)
331
+ p.data.add_(-step_size, torch.mul(p.data, group['weight_decay']).addcdiv_(1, exp_avg, denom) )
332
+
333
+ return loss
334
+
335
+
336
+ class RangerGC(Optimizer):
337
+
338
+ def __init__(self, params, lr=1e-3, k=5, alpha=0.5, n_sma_threshhold=5, betas=(0.95,0.999),
339
+ eps=1e-8, weight_decay=0, amsgrad=True, transformer='softplus', smooth=50,
340
+ grad_transformer='square', correct_bias=False):
341
+ if not 0.0 <= alpha <= 1.0:
342
+ raise ValueError(f'Invalid slow update rate: {alpha}')
343
+ if not 1 <= k:
344
+ raise ValueError(f'Invalid lookahead steps: {k}')
345
+ if not lr > 0:
346
+ raise ValueError(f'Invalid Learning Rate: {lr}')
347
+ if not eps > 0:
348
+ raise ValueError(f'Invalid eps: {eps}')
349
+
350
+ defaults = dict(lr=lr, k=k, alpha=alpha, step_counter=0, betas=betas,
351
+ n_sma_threshhold=n_sma_threshhold, eps=eps, weight_decay=weight_decay,
352
+ smooth=smooth, transformer=transformer, grad_transformer=grad_transformer,
353
+ amsgrad=amsgrad, correct_bias=correct_bias)
354
+ super().__init__(params, defaults)
355
+
356
+ # adjustable threshold
357
+ self.n_sma_threshhold = n_sma_threshhold
358
+
359
+ # lookahead params
360
+ self.alpha = alpha
361
+ self.k = k
362
+
363
+ # radam buffer for state
364
+ self.radam_buffer = [[None,None,None] for ind in range(10)]
365
+
366
+ def __setstate__(self, state):
367
+ super(RangerGC, self).__setstate__(state)
368
+
369
+
370
+ def step(self, closure=None):
371
+ loss = None
372
+ if closure is not None:
373
+ loss = closure()
374
+
375
+ # Evaluate averages and grad, update param tensors
376
+ for group in self.param_groups:
377
+
378
+ for p in group['params']:
379
+ if p.grad is None:
380
+ continue
381
+ grad = p.grad.data.float()
382
+ if grad.is_sparse:
383
+ raise RuntimeError('Ranger optimizer does not support sparse gradients')
384
+
385
+ amsgrad = group['amsgrad']
386
+ smooth = group['smooth']
387
+ grad_transformer = group['grad_transformer']
388
+
389
+ p_data_fp32 = p.data.float()
390
+
391
+ state = self.state[p]
392
+
393
+ if len(state) == 0:
394
+ state['step'] = 0
395
+ state['exp_avg'] = torch.zeros_like(p_data_fp32)
396
+ state['exp_avg_sq'] = torch.zeros_like(p_data_fp32)
397
+ if amsgrad:
398
+ # Maintains max of all exp. moving avg. of sq. grad. values
399
+ state['max_exp_avg_sq'] = torch.zeros_like(p.data)
400
+
401
+ # lookahead weight storage now in state dict
402
+ state['slow_buffer'] = torch.empty_like(p.data)
403
+ state['slow_buffer'].copy_(p.data)
404
+
405
+ else:
406
+ state['exp_avg'] = state['exp_avg'].type_as(p_data_fp32)
407
+ state['exp_avg_sq'] = state['exp_avg_sq'].type_as(p_data_fp32)
408
+
409
+ exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']
410
+ beta1, beta2 = group['betas']
411
+ if amsgrad:
412
+ max_exp_avg_sq = state['max_exp_avg_sq']
413
+
414
+
415
+ # compute variance mov avg
416
+ exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad)
417
+ # compute mean moving avg
418
+ exp_avg.mul_(beta1).add_(1 - beta1, grad)
419
+
420
+ # transformer
421
+ if grad_transformer == 'square':
422
+ grad_tmp = grad**2
423
+ elif grad_transformer == 'abs':
424
+ grad_tmp = grad.abs()
425
+
426
+ exp_avg_sq.mul_(beta2).add_((1 - beta2)*grad_tmp)
427
+
428
+ if amsgrad:
429
+ # Maintains the maximum of all 2nd moment running avg. till now
430
+ torch.max(max_exp_avg_sq, exp_avg_sq, out=max_exp_avg_sq)
431
+ # Use the max. for normalizing running avg. of gradient
432
+ denomc = max_exp_avg_sq.clone()
433
+ else:
434
+ denomc = exp_avg_sq.clone()
435
+
436
+ if grad_transformer == 'square':
437
+ denomc.sqrt_()
438
+
439
+ # GC operation for Conv layers and FC layers
440
+ length = len(list(p.data.size()))
441
+ if length > 1:
442
+ grad.add_(-grad.mean(dim=tuple(range(1, length)), keepdim=True))
443
+
444
+ state['step'] += 1
445
+
446
+ if group['weight_decay'] > 0:
447
+ p_data_fp32.add_(-group['weight_decay'] * group['lr'], p_data_fp32)
448
+
449
+ step_size = group["lr"]
450
+ if group["correct_bias"]: # No bias correction for Bert
451
+ bias_correction1 = 1.0 - beta1 ** state["step"]
452
+ bias_correction2 = 1.0 - beta2 ** state["step"]
453
+ step_size = step_size * math.sqrt(bias_correction2) / bias_correction1
454
+
455
+ if group['transformer'] =='softplus':
456
+ sp = torch.nn.Softplus(smooth)
457
+ denomf = sp(denomc)
458
+ p_data_fp32.addcdiv_(-step_size, exp_avg, denomf)
459
+ else:
460
+ denom = exp_avg_sq.sqrt().add_(group['eps'])
461
+ p_data_fp32.addcdiv_(-step_size * group['lr'], exp_avg, denom)
462
+
463
+ p.data.copy_(p_data_fp32)
464
+
465
+ # Integrated lookahead...
466
+ # We do it at the param level instead of group level
467
+ if state['step'] % group['k'] == 0:
468
+ slow_p = state['slow_buffer'] # get access to slow param tensor
469
+ slow_p.add_(self.alpha, p.data - slow_p) # (fast weights - slow weights) * alpha
470
+ p.data.copy_(slow_p) # copy interpolated weights to RAdam param tensor
471
+
472
+ return loss
ai/tensor/__init__.py ADDED
@@ -0,0 +1,25 @@
1
+ import torch
2
+
3
+
4
+ def tensor2list(tensor):
5
+ '''将张量转换为列表
6
+ '''
7
+ return tensor.detach().cpu().tolist()
8
+
9
+
10
+ def cat(tensors, dim=0):
11
+ """更高效的 torch.cat 版本,避免在只有一个元素时复制原张量
12
+ """
13
+ assert isinstance(tensors, (list, tuple))
14
+ if len(tensors) == 1:
15
+ return tensors[0]
16
+ return torch.cat(tensors, dim)
17
+
18
+
19
+ def contiguous(tensor):
20
+ '''获取连续存储的张量
21
+ '''
22
+ if tensor.is_contiguous():
23
+ return tensor
24
+ else:
25
+ return tensor.contiguous()
ai/trainer/__init__.py ADDED
@@ -0,0 +1,18 @@
1
+ import os
2
+ import numpy as np
3
+ import random
4
+ import torch
5
+
6
+
7
+ def set_seed(seed, n_gpu=1):
8
+ '''设置随机种子
9
+ '''
10
+ os.environ['PYTHONHASHSEED'] = str(seed)
11
+ random.seed(seed)
12
+ np.random.seed(seed)
13
+ torch.manual_seed(seed)
14
+ if n_gpu > 0:
15
+ torch.cuda.manual_seed(seed)
16
+ torch.cuda.manual_seed_all(seed)
17
+ torch.backends.cudnn.deterministic = True
18
+ torch.backends.cudnn.benchmark = True
ai/utils/__init__.py ADDED
@@ -0,0 +1,26 @@
1
+ import os
2
+ import bz2
3
+
4
+
5
+ def ensure_dir(dir_path):
6
+ '''确保单个目录存在
7
+ '''
8
+ if not os.path.exists(dir_path):
9
+ os.makedirs(dir_path)
10
+
11
+
12
+ def ensure_dirs(dir_list):
13
+ '''确保多个目录存在
14
+ '''
15
+ for dir_path in dir_list:
16
+ ensure_dir(dir_path)
17
+
18
+
19
+ def unpack_bz2(src_path):
20
+ '''解压 bz2 文件
21
+ '''
22
+ data = bz2.BZ2File(src_path).read()
23
+ dst_path = src_path[:-4]
24
+ with open(dst_path, 'wb') as fp:
25
+ fp.write(data)
26
+ return dst_path
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.4
2
+ Name: ai
3
+ Version: 1.1.1
4
+ Summary: Ai lib.
5
+ Home-page: https://github.com/Decalogue/ai
6
+ Author: Decalogue
7
+ Author-email: 1044908508@qq.com
8
+ License: MIT
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Information Technology
13
+ Classifier: Natural Language :: English
14
+ Classifier: Natural Language :: Chinese (Simplified)
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Operating System :: MacOS :: MacOS X
19
+ Classifier: Operating System :: Other OS
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/x-rst
27
+ Dynamic: author
28
+ Dynamic: author-email
29
+ Dynamic: classifier
30
+ Dynamic: description
31
+ Dynamic: description-content-type
32
+ Dynamic: home-page
33
+ Dynamic: license
34
+ Dynamic: requires-python
35
+ Dynamic: summary
36
+
37
+ Ai lib.
@@ -0,0 +1,15 @@
1
+ ai/__init__.py,sha256=E-6wAZjiLRVInABFxrWoqdYlO_t-zVhK8XNfNnaDyzI,22
2
+ ai/config.py,sha256=rlgDA990_SdbNNtoPnB48Gg0gGkEyvxzTdMo6dplpmg,3571
3
+ ai/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ ai/data/augment.py,sha256=05zxXdwiXG1L-eoQd8Uz8f7wyUZhdf-a0w2jDldtrcA,14188
5
+ ai/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ ai/llm/postprocess.py,sha256=37XykIrCleMJ674dqfBovab0_bLy5BMF0lFHuBnSNRQ,3314
7
+ ai/optim/__init__.py,sha256=TJuUat9jw_6bkeQhQ5e5rXMvedV8fUpJj2N6rxwbeFw,21346
8
+ ai/tensor/__init__.py,sha256=gXpXpnD1RLiaVSgKI9KEU4K0Hx6NJ6XZY8GGurqNXF0,542
9
+ ai/trainer/__init__.py,sha256=LuN8w4K-Wu7KbhjuoSr0oki6Iap8YbQWNzLGJjGT3Do,425
10
+ ai/utils/__init__.py,sha256=xGOyk8BzlHyDCNrZlakPfDewRPIXVJOOJd41MYhIDmo,493
11
+ tests/__init__.py,sha256=83Ndli5J42Tcuq58g7r-XLkeebJaKlazC_Gi2fBezE4,108
12
+ ai-1.1.1.dist-info/METADATA,sha256=mo3nRkCsvILXulrRcZwckI2EL1gX_gnqvwuK1gOPJjA,1194
13
+ ai-1.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ ai-1.1.1.dist-info/top_level.txt,sha256=8u8HzGvcQsdPD992eODUIMuDjQ_EdzUnYySgx4Tfw8o,9
15
+ ai-1.1.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ ai
2
+ tests
tests/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from __future__ import absolute_import
2
+ from __future__ import division
3
+ from __future__ import print_function