TkskKurumi commited on
Commit
01906b8
·
1 Parent(s): 739227f

Upload 2 files

Browse files
Files changed (2) hide show
  1. merge.bash +7 -0
  2. my_merge_lora.py +151 -0
merge.bash ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ python3 my_merge_lora.py\
2
+ --base_model ~/autodl-tmp/RWKV-4-Raven-7B-v11-Eng49%-Chn49%-Jpn1%-Other1%-20230430-ctx8192.pth\
3
+ --lora_load ~/RWKV_Train/save_7B_128/rwkv-12.pth\
4
+ --save ~/autodl-tmp/lora_7B.pth\
5
+ --lora_schedule poly\
6
+ --plot\
7
+ --lora_strategy "0:64,0.3:32,0.4:0,0.5:32,1:64"
my_merge_lora.py ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from matplotlib import pyplot as plt
2
+ import numpy as np
3
+ from collections import OrderedDict
4
+ import os
5
+ from tqdm import tqdm
6
+ import sys
7
+ from typing import Dict
8
+ import typing
9
+ import torch
10
+ import argparse
11
+ parser = argparse.ArgumentParser()
12
+ parser.add_argument("--base_model", type=str, required=True)
13
+ parser.add_argument("--lora_load", type=str, required=True)
14
+ parser.add_argument("--lora_schedule", type=str, default="const", choices=["const", "linear", "poly"])
15
+ parser.add_argument("--lora_alpha", type=float, default=None)
16
+ parser.add_argument("--lora_beta", type=float, default=None)
17
+ parser.add_argument("--lora_strategy", type=str, default=None)
18
+ parser.add_argument("--plot", action="store_true")
19
+ parser.add_argument("--save", required=True, type=str)
20
+ args = parser.parse_args()
21
+
22
+ def f_const(alpha):
23
+ def inner(x):
24
+ return alpha
25
+ return inner
26
+ def f_linear(alpha, beta):
27
+ def inner(x):
28
+ return alpha+x*(beta-alpha)
29
+ return inner
30
+
31
+ def f_polyline(*args):
32
+ args = sorted(args)
33
+ xs = []
34
+ ys = []
35
+ xys = args
36
+ for x, y in args:
37
+ xs.append(x)
38
+ ys.append(y)
39
+ def inner(x):
40
+ if(x<=xs[0]):
41
+ return ys[0]
42
+ if(x>=xs[-1]):
43
+ return ys[-1]
44
+ for i, x1 in enumerate(xs):
45
+ x0 = xs[i-1]
46
+ if(x0<=x and x<=x1):
47
+ y0 = ys[i-1]
48
+ y1 = ys[i]
49
+ n = (x-x0)/(x1-x0)
50
+ y = y0*(1-n)+y1*n
51
+ return y
52
+ return ys[-1]
53
+ return inner
54
+
55
+
56
+ with torch.no_grad():
57
+ base = args.base_model
58
+ lora = args.lora_load
59
+ w: Dict[str, torch.Tensor] = torch.load(base, map_location="cpu")
60
+ w_lora: Dict[str, torch.Tensor] = torch.load(lora, map_location="cpu")
61
+ out: typing.OrderedDict[str, torch.Tensor] = OrderedDict()
62
+
63
+ tuned_weights = []
64
+
65
+ lora_rank = None
66
+ listkeys = list(w.keys())
67
+ for key in listkeys:
68
+ if key.endswith(".weight"):
69
+ pref = key[:-len(".weight")]
70
+ key_A = pref+".lora_A"
71
+ key_B = pref+".lora_B"
72
+ if(key_A in w_lora and key_B in w_lora):
73
+ print("Weight %s will be merged with lora"%pref)
74
+ tuned_weights.append(key)
75
+
76
+ if(lora_rank is None):
77
+ lora_A = w_lora[key_A]
78
+ lora_B = w_lora[key_B]
79
+ lora_rank = lora_A.shape[0]
80
+ assert lora_rank == lora_B.shape[1]
81
+
82
+
83
+ if(args.lora_schedule == "const"):
84
+ alpha = args.lora_alpha
85
+ if(alpha is None):
86
+ print("assuming lora_alpha = lora_rank = %s"%lora_rank)
87
+ alpha = lora_rank
88
+ f_schedule = f_const(alpha)
89
+ elif(args.lora_schedule == "poly"):
90
+ xys = []
91
+ for i in args.lora_strategy.split(","):
92
+ xy = [float(_) for _ in i.split(":")]
93
+ xys.append(xy)
94
+ f_schedule = f_polyline(*xys)
95
+ else:
96
+ alpha = args.lora_alpha
97
+ beta = args.lora_beta
98
+ if(alpha is None):
99
+ print("assuming lora_alpha = lora_rank = %s"%lora_rank)
100
+ alpha = lora_rank
101
+ if(beta is None):
102
+ print("assuming beta = lora_rank = %s"%lora_rank)
103
+ beta = lora_rank
104
+ f_schedule = f_linear(alpha, beta)
105
+
106
+ weight2alpha = {}
107
+ for idx, i in enumerate(tuned_weights):
108
+ # assuming weights are fetched in depth order
109
+ depth = idx
110
+ if(len(tuned_weights)>1):
111
+ depth = depth/(len(tuned_weights)-1)
112
+ else:
113
+ depth = 0.5
114
+ alpha = f_schedule(depth)
115
+ print("%s: alpha=%.3f, alpha/rank=%.2f"%(i, alpha, alpha/lora_rank))
116
+ weight2alpha[i] = alpha
117
+ if(args.plot):
118
+ tot = 32
119
+ xs = np.linspace(0, tot-1, tot)
120
+ ys = [f_schedule(x/(tot-1)) for x in xs]
121
+ plt.plot(xs, ys)
122
+ plt.savefig(args.save+".png")
123
+ print("plot", args.save+".png")
124
+ for key in tqdm(listkeys):
125
+ if(key in tuned_weights):
126
+ pref = key[:-len(".weight")]
127
+ key_A = pref+".lora_A"
128
+ key_B = pref+".lora_B"
129
+
130
+ lora_A = w_lora[key_A]
131
+ lora_B = w_lora[key_B]
132
+ lora_rank = lora_A.shape[0]
133
+ assert lora_rank == lora_B.shape[1]
134
+
135
+ delta_w = (lora_B @ lora_A)*weight2alpha[key]/lora_rank
136
+ new_w = w[key]+delta_w
137
+ out_w = new_w.to(device=w[key].device, dtype=w[key].dtype, copy=True)
138
+ out[key] = out_w
139
+ del w[key]
140
+ else:
141
+ # print("%s = original"%(key))
142
+ out[key] = w[key].clone()
143
+ del w[key]
144
+ # assert list(out.keys()) == list(w.keys())
145
+ # for key in out.keys():
146
+ # assert out[key].shape == w[key].shape
147
+ # assert out[key].dtype == w[key].dtype
148
+
149
+
150
+ torch.save(out, args.save)
151
+ print("saved", args.save)