-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
488 lines (251 loc) · 190 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>ANdRoid's BLOG</title>
<subtitle>MaTRix</subtitle>
<link href="https://zade23.github.io/atom.xml" rel="self"/>
<link href="https://zade23.github.io/"/>
<updated>2025-01-16T07:02:53.808Z</updated>
<id>https://zade23.github.io/</id>
<author>
<name>Android</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>【工具】个人向SSH工具及相关设置</title>
<link href="https://zade23.github.io/2025/01/16/%E3%80%90%E5%B7%A5%E5%85%B7%E3%80%91%E4%B8%AA%E4%BA%BA%E5%90%91SSH%E5%B7%A5%E5%85%B7%E5%8F%8A%E7%9B%B8%E5%85%B3%E8%AE%BE%E7%BD%AE/"/>
<id>https://zade23.github.io/2025/01/16/%E3%80%90%E5%B7%A5%E5%85%B7%E3%80%91%E4%B8%AA%E4%BA%BA%E5%90%91SSH%E5%B7%A5%E5%85%B7%E5%8F%8A%E7%9B%B8%E5%85%B3%E8%AE%BE%E7%BD%AE/</id>
<published>2025-01-16T06:56:19.000Z</published>
<updated>2025-01-16T07:02:53.808Z</updated>
<content type="html"><![CDATA[<ul><li><a href="#ssh%E5%B7%A5%E5%85%B7">SSH工具</a></li><li><a href="#%E9%85%8D%E8%89%B2%E6%96%B9%E6%A1%88">配色方案</a></li><li><a href="#%E5%AD%97%E4%BD%93">字体</a></li><li><a href="#%E6%8C%89%E9%94%AE%E8%AE%BE%E7%BD%AE">按键设置</a></li><li><a href="#tmux%E9%85%8D%E7%BD%AE">Tmux配置</a><ul><li><a href="#%E9%BC%A0%E6%A0%87%E5%8D%8F%E5%8A%A9">鼠标协助</a></li></ul></li><li><a href="#%E6%9C%80%E7%BB%88%E6%95%88%E6%9E%9C">最终效果</a></li><li><a href="#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5">参考链接</a></li></ul><h2 id="SSH工具"><a href="#SSH工具" class="headerlink" title="SSH工具"></a>SSH工具</h2><p>SSH终端:Putty</p><p>分屏/后台工具: Tmux</p><h2 id="配色方案"><a href="#配色方案" class="headerlink" title="配色方案"></a>配色方案</h2><p>可从 <a href="https://putty.org.ru/themes">PuTTY Color Themes</a> 上找</p><p>我个人使用的主题:<a href="https://putty.org.ru/themes/igvita-desert">19. Igvita Desert</a></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">Windows Registry Editor Version 5.00</span><br><span class="line"></span><br><span class="line">[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\<填写你想要适配的保存方案,没有就不填>]</span><br><span class="line">"Colour0"="255,255,255"</span><br><span class="line">"Colour1"="255,255,255"</span><br><span class="line">"Colour2"="51,51,51"</span><br><span class="line">"Colour3"="85,85,85"</span><br><span class="line">"Colour4"="0,0,0"</span><br><span class="line">"Colour5"="0,255,0"</span><br><span class="line">"Colour6"="77,77,77"</span><br><span class="line">"Colour7"="85,85,85"</span><br><span class="line">"Colour8"="255,43,43"</span><br><span class="line">"Colour9"="255,85,85"</span><br><span class="line">"Colour10"="152,251,152"</span><br><span class="line">"Colour11"="85,255,85"</span><br><span class="line">"Colour12"="240,230,140"</span><br><span class="line">"Colour13"="255,255,85"</span><br><span class="line">"Colour14"="205,133,63"</span><br><span class="line">"Colour15"="135,206,235"</span><br><span class="line">"Colour16"="255,222,173"</span><br><span class="line">"Colour17"="255,85,255"</span><br><span class="line">"Colour18"="255,160,160"</span><br><span class="line">"Colour19"="255,215,0"</span><br><span class="line">"Colour20"="245,222,179"</span><br><span class="line">"Colour21"="255,255,255"</span><br></pre></td></tr></table></figure><h2 id="字体"><a href="#字体" class="headerlink" title="字体"></a>字体</h2><p>在设置中依次点击:<code>Window → Appearance → Font settings: Change……</code></p><p>console,粗体,10</p><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202501161133280.png" alt="console,粗体,10"></p><h2 id="按键设置"><a href="#按键设置" class="headerlink" title="按键设置"></a>按键设置</h2><p>解决大部分键位映射的问题</p><ol><li><p>将 “The Function keys and keypad” 设置更改为 **”Xterm R6”**。</p></li><li><p>将 “Shift/Ctrl/Alt with the arrow keys” 设置更改为 **”xterm-style bitmap”**。</p></li></ol><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202501161131787.png" alt="The Function keys and keypad"></p><h2 id="Tmux配置"><a href="#Tmux配置" class="headerlink" title="Tmux配置"></a>Tmux配置</h2><p>安装Tmux界面美化: <a href="https://github.com/gpakosz/.tmux">https://github.com/gpakosz/.tmux</a></p><h3 id="鼠标协助"><a href="#鼠标协助" class="headerlink" title="鼠标协助"></a>鼠标协助</h3><p>找到 <code>.tmux.conf.local</code>文件修改Tmux设置</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim .tmux.conf.local</span><br></pre></td></tr></table></figure><p>把 <code>set -g mouse on</code> 这一行取消注释即可</p><figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># start with mouse mode enabled</span><br><span class="line">set -g mouse on</span><br></pre></td></tr></table></figure><h2 id="最终效果"><a href="#最终效果" class="headerlink" title="最终效果"></a>最终效果</h2><p>Tmux界面:</p><table><thead><tr><th><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202501161140104.png" alt="Tmux界面1"></th><th><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202501161157725.png" alt="Tmux界面2"></th></tr></thead></table><p>bash界面:</p><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202501161142782.png" alt="bash界面"></p><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><ul><li><a href="https://blog.csdn.net/Pan_peter/article/details/124510524">Linux——putty颜色设置【如何改变颜色】-CSDN博客</a></li><li><a href="https://github.com/AlexAkulov/putty-color-themes">GitHub - AlexAkulov/putty-color-themes: PuTTY Color Themes</a></li></ul>]]></content>
<summary type="html"><ul>
<li><a href="#ssh%E5%B7%A5%E5%85%B7">SSH工具</a></li>
<li><a href="#%E9%85%8D%E8%89%B2%E6%96%B9%E6%A1%88">配色方案</a></li>
<li><a href="#%E5</summary>
</entry>
<entry>
<title>【随笔】如何克服拖延症?</title>
<link href="https://zade23.github.io/2024/12/17/%E5%A6%82%E4%BD%95%E5%85%8B%E6%9C%8D%E6%8B%96%E5%BB%B6%E7%97%87%EF%BC%9F/"/>
<id>https://zade23.github.io/2024/12/17/%E5%A6%82%E4%BD%95%E5%85%8B%E6%9C%8D%E6%8B%96%E5%BB%B6%E7%97%87%EF%BC%9F/</id>
<published>2024-12-17T03:47:30.000Z</published>
<updated>2024-12-17T07:10:10.479Z</updated>
<content type="html"><![CDATA[<ul><li><a href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E6%8B%96%E5%BB%B6">为什么会拖延?</a></li><li><a href="#%E5%A4%84%E7%90%86%E6%96%B9%E6%B3%95">处理方法</a><ul><li><a href="#%E8%B0%83%E5%8A%A8%E6%83%85%E7%BB%AA">调动情绪</a></li><li><a href="#%E5%A4%A7%E4%BD%AC%E4%BB%AC%E7%9A%84%E5%BB%BA%E8%AE%AE">大佬们的建议</a></li></ul></li><li><a href="#%E6%80%BB%E7%BB%93">总结</a></li><li><a href="#%E7%9B%B8%E5%85%B3%E5%8F%82%E8%80%83">相关参考</a></li></ul><hr><h2 id="为什么会拖延?"><a href="#为什么会拖延?" class="headerlink" title="为什么会拖延?"></a>为什么会拖延?</h2><p>大部分情况下的拖延因素来源于“畏难情绪”。</p><p>通常,被拖延的任务要么是重要的任务,要么是比较困难的任务。面对这样的任务,我们会在大脑中放大这个问题的困难程度,放大的原因在于:不熟悉。</p><p>除了拖延症,此前张朝阳还谈起过如何摆脱焦虑的困扰。他介绍称:“在心理学上有一个像物理学里的牛顿定律一样的定律,就是当我们想要去解决焦虑的时候,焦虑就会被放大。所以面对焦虑的时候不要回避,不去解决。而去接受、无视。”</p><h2 id="处理方法"><a href="#处理方法" class="headerlink" title="处理方法"></a>处理方法</h2><h3 id="调动情绪"><a href="#调动情绪" class="headerlink" title="调动情绪"></a>调动情绪</h3><p>第一步,收集信息。</p><p>信息收集的过程是熟悉任务的过程。在收集的同时,和自己进行“对话”</p><blockquote><p>“完成这个事是需要这个、需要那个……”<br>“这个跟那个之间有什么关系……”</p></blockquote><p>通过这样的方式,让自己的大脑神经元被充分调动,让自己excited。当情绪调动起来了,一鼓作气的将它完成。</p><h3 id="大佬们的建议"><a href="#大佬们的建议" class="headerlink" title="大佬们的建议"></a>大佬们的建议</h3><ol><li><strong>不做过度的准备</strong>(不需要找个舒服环境再开始工作。先完成,再完美,完善的过程问题会越来越多,最终杀死了灵感和信心)</li><li><strong>最难的事情,提前做</strong>(难做的事情放在早上先做)</li><li><strong>不要中途休息</strong>(最好不要有思维的中断,有思路的事情一鼓作气解决)</li><li><strong>不要抱有太强的目标感</strong>(经历只能参考,不能复制。在过程中见招拆招,遇到问题解决问题)</li><li><strong>事情一件一件做</strong>(按照难易程度划分,从难往易一件一件解决)</li><li><strong>拖延也要有度</strong>(有最晚启动时间底线)</li></ol><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>深度学习领域大牛李沐老师,在上海交通大学进行讲话就提到了:“<strong>找到强烈的动机。</strong>”</p><p>在这里同时分享一句我个人很喜欢的一句话(同样出自李沐老师):“<strong>一个很好的创业人或者CEO,他一定是理想主义者兼实践者。</strong>”</p><p>我的理解是:坚信自己最终的理想是正确的,同时脚踏实地一步一步干出成绩来。</p><p>下面的这句话有同样的含义:</p><blockquote><p>“<strong>尽早确立人生价值观,无论什么情绪来了,都按照价值观坚定的、积极的生活和工作。</strong>” ——张朝阳</p></blockquote><p>一句话:找到你内心最想做的事情,追随你的内心。</p><h2 id="相关参考"><a href="#相关参考" class="headerlink" title="相关参考"></a>相关参考</h2><ul><li><a href="https://www.bilibili.com/video/BV1JG4y197gS/">张朝阳谈摆脱拖延的方法:拖延的原因在于不熟悉</a></li><li><a href="https://www.bilibili.com/video/BV1zmymYHERs/">杰出系友专访|@BosonAI李沐:找到强烈的动机</a></li></ul>]]></content>
<summary type="html"><ul>
<li><a href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E6%8B%96%E5%BB%B6">为什么会拖延?</a></li>
<li><a href="#%E5%A4%84%E7%90%86%E6%96%B9%E6%B3%</summary>
</entry>
<entry>
<title>【DSA】LeetCode_Hot100</title>
<link href="https://zade23.github.io/2024/10/31/%E3%80%90DSA%E3%80%91LeetCode-Hot100/"/>
<id>https://zade23.github.io/2024/10/31/%E3%80%90DSA%E3%80%91LeetCode-Hot100/</id>
<published>2024-10-31T02:34:32.000Z</published>
<updated>2024-10-31T03:28:56.597Z</updated>
<category term="数据结构和算法" scheme="https://zade23.github.io/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/"/>
<category term="LeetCode" scheme="https://zade23.github.io/tags/LeetCode/"/>
</entry>
<entry>
<title>模型训练库缺失 ImportError: No xformers</title>
<link href="https://zade23.github.io/2024/07/03/%E6%A8%A1%E5%9E%8B%E8%AE%AD%E7%BB%83%E5%BA%93%E7%BC%BA%E5%A4%B1-ImportError-No-xformers/"/>
<id>https://zade23.github.io/2024/07/03/%E6%A8%A1%E5%9E%8B%E8%AE%AD%E7%BB%83%E5%BA%93%E7%BC%BA%E5%A4%B1-ImportError-No-xformers/</id>
<published>2024-07-03T12:03:21.000Z</published>
<updated>2024-07-03T12:08:56.675Z</updated>
<content type="html"><![CDATA[<h3 id="发现问题"><a href="#发现问题" class="headerlink" title="发现问题"></a>发现问题</h3><p>借助Lora训练Diffusion模型的时候,出现了报错:</p><p><code>ImportError: No xformers</code></p><h3 id="分析问题"><a href="#分析问题" class="headerlink" title="分析问题"></a>分析问题</h3><p>安装对应版本的Transformer模型即可解决问题,参考:<a href="https://github.com/Akegarasu/lora-scripts/issues/422#issuecomment-2127945481">https://github.com/Akegarasu/lora-scripts/issues/422#issuecomment-2127945481</a></p><h3 id="解决问题"><a href="#解决问题" class="headerlink" title="解决问题"></a>解决问题</h3><p>找到当前运行训练任务的机器,确定对应的版本:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> torch</span><br><span class="line">pirnt(torch.__version__)</span><br><span class="line"></span><br><span class="line"><span class="meta">>>> </span><span class="number">2.3</span><span class="number">.1</span> + cu121</span><br></pre></td></tr></table></figure><p>从输出定位 <strong>torch版本</strong> 和 <strong>cuda版本</strong>,从 <a href="https://github.com/facebookresearch/xformers?tab=readme-ov-file#installing-xformers">https://github.com/facebookresearch/xformers?tab=readme-ov-file#installing-xformers</a> 找 torch + cuda + xformers 三者关系都能对应上的版本。</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># cuda 12.1 version</span></span><br><span class="line">pip3 install -U xformers --index-url https://download.pytorch.org/whl/cu121</span><br></pre></td></tr></table></figure><p>安装成功,问题解决。</p>]]></content>
<summary type="html"><h3 id="发现问题"><a href="#发现问题" class="headerlink" title="发现问题"></a>发现问题</h3><p>借助Lora训练Diffusion模型的时候,出现了报错:</p>
<p><code>ImportError: No xfo</summary>
<category term="Deeplearning" scheme="https://zade23.github.io/categories/Deeplearning/"/>
<category term="conda" scheme="https://zade23.github.io/tags/conda/"/>
<category term="environment" scheme="https://zade23.github.io/tags/environment/"/>
</entry>
<entry>
<title>【阅读】Ilya的论文阅读清单</title>
<link href="https://zade23.github.io/2024/05/27/%E3%80%90%E9%98%85%E8%AF%BB%E3%80%91Ilya%E7%9A%84%E8%AE%BA%E6%96%87%E9%98%85%E8%AF%BB%E6%B8%85%E5%8D%95/"/>
<id>https://zade23.github.io/2024/05/27/%E3%80%90%E9%98%85%E8%AF%BB%E3%80%91Ilya%E7%9A%84%E8%AE%BA%E6%96%87%E9%98%85%E8%AF%BB%E6%B8%85%E5%8D%95/</id>
<published>2024-05-27T06:35:39.000Z</published>
<updated>2024-05-27T07:01:34.542Z</updated>
<content type="html"><![CDATA[<ul><li><a href="#%E8%83%8C%E6%99%AF%E4%BB%8B%E7%BB%8D">背景介绍</a></li><li><a href="#%E4%B8%BB%E8%A6%81%E5%86%85%E5%AE%B9">主要内容</a><ul><li><a href="#%E6%A0%B8%E5%BF%83%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%88%9B%E6%96%B0">核心神经网络创新</a></li><li><a href="#%E4%B8%93%E4%B8%9A%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%BA%94%E7%94%A8">专业神经网络应用</a></li><li><a href="#%E7%90%86%E8%AE%BA%E8%A7%81%E8%A7%A3%E5%92%8C%E5%8E%9F%E5%88%99%E6%80%A7%E6%96%B9%E6%B3%95">理论见解和原则性方法</a></li><li><a href="#%E8%B7%A8%E5%AD%A6%E7%A7%91%E5%92%8C%E6%A6%82%E5%BF%B5%E7%A0%94%E7%A9%B6">跨学科和概念研究</a></li><li><a href="#%E6%95%88%E7%8E%87%E5%92%8C%E5%8F%AF%E6%89%A9%E5%B1%95%E6%80%A7%E6%8A%80%E6%9C%AF">效率和可扩展性技术</a></li><li><a href="#%E6%95%99%E6%9D%90%E5%92%8C%E6%95%99%E7%A8%8B">教材和教程</a></li></ul></li></ul><h2 id="背景介绍"><a href="#背景介绍" class="headerlink" title="背景介绍"></a>背景介绍</h2><p>Ilya Sutskever 的论文清单:<a href="https://arc.net/folder/D0472A20-9C20-4D3F-B145-D2865C0A9FEE?source=post_page-----3bd4c9f8e927--------------------------------">30u30</a></p><p>Ilya Sutskever 是 Hinton 的大弟子,OpenAI的联合创始人兼首席科学家。</p><p>以下是他推荐的论文清单,他认为阅读完这些内容之后就可以了解AI领域90%的内容</p><h2 id="主要内容"><a href="#主要内容" class="headerlink" title="主要内容"></a>主要内容</h2><h3 id="核心神经网络创新"><a href="#核心神经网络创新" class="headerlink" title="核心神经网络创新"></a>核心神经网络创新</h3><ol><li><a href="https://arxiv.org/abs/1409.2329?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Recurrent Neural Network Regularization</a> - Enhancement to LSTM units for better overfitting prevention.<br>递归神经网络正则化 - 增强了 LSTM 单元,以更好地防止过拟合。</li><li><a href="https://arxiv.org/abs/1506.03134?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Pointer Networks</a> - Novel architecture for solving problems with discrete token outputs.<br> Pointer Networks - 用于解决离散令牌输出问题的新颖架构.</li><li><a href="https://arxiv.org/abs/1512.03385?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Deep Residual Learning for Image Recognition</a> - Improvements for training very deep networks through residual learning.<br> 用于图像识别的深度残差学习 - 改进了通过残差学习训练非常深度的网络。</li><li><a href="https://arxiv.org/abs/1603.05027?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Identity Mappings in Deep Residual Networks</a> - Enhancements to deep residual networks through identity mappings.<br> 深度残差网络中的身份映射 - 通过身份映射增强深度残差网络。</li><li><a href="https://arxiv.org/abs/1512.02595?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Neural Turing Machines</a> - Combining neural networks with external memory resources for enhanced algorithmic tasks.<ul><li>将神经网络与外部内存资源相结合,以增强算法任务。</li></ul></li><li><a href="https://arxiv.org/abs/1706.03762?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Attention Is All You Need</a> - Introducing the Transformer architecture solely based on attention mechanisms.<br> Attention Is All You Need - 介绍完全基于注意力机制的 Transformer 架构。</li></ol><h3 id="专业神经网络应用"><a href="#专业神经网络应用" class="headerlink" title="专业神经网络应用"></a>专业神经网络应用</h3><ul><li><a href="https://arxiv.org/abs/1511.07122?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Multi-Scale Context Aggregation by Dilated Convolutions</a> - A convolutional network module for better semantic segmentation.<br> Multi-Scale Context Aggregation by Dilated Convolutions - 一个卷积网络模块,用于更好的语义分割.</li><li><a href="https://arxiv.org/abs/1409.0473?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Neural Machine Translation by Jointly Learning to Align and Translate</a> - A model improving translation by learning to align and translate concurrently.<br> Neural Machine Translation by Joint Learning to Align and Translation - 一种通过学习同时对齐和翻译来改进翻译的模型.</li><li><a href="https://arxiv.org/abs/1704.01212?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Neural Message Passing for Quantum Chemistry</a> - A framework for learning on molecular graphs for quantum chemistry.<br> Neural Message Passing for Quantum Chemistry - 量子化学分子图学习框架.</li><li><a href="https://arxiv.org/abs/1806.01822?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Relational RNNs</a> - Enhancement to standard memory architectures integrating relational reasoning capabilities.Theoretical and Principled Approaches<br> 关系 RNN - 增强了集成关系推理功能的标准内存架构。理论和原则方法</li><li><a href="https://arxiv.org/abs/1512.02595?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Deep Speech 2: End-to-End Speech Recognition in English and Mandarin</a> - Deep learning system for speech recognition.<br> Deep Speech 2: End-to-End Speech Recognition in English and Mandarin -用于语音识别的深度学习系统.</li><li><a href="https://proceedings.neurips.cc/paper_files/paper/2012/file/c399862d3b9d6b76c8436e924a68c45b-Paper.pdf?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">ImageNet Classification with Deep CNNs</a> - Convolutional neural network for classifying large-scale image data.<br> ImageNet Classification with Deep CNNs - 用于对大规模图像数据进行分类的卷积神经网络.</li><li><a href="https://arxiv.org/abs/1611.02731?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Variational Lossy Autoencoder</a> - Combines VAEs and autoregressive models for improved image synthesis.<br> 变分有损自动编码器 - 结合 VAE 和自回归模型以改进图像合成。</li><li><a href="https://arxiv.org/abs/1706.01427?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">A Simple NN Module for Relational Reasoning</a> - A neural module designed to improve relational reasoning in AI tasks.<br> 用于关系推理的简单神经网络模块 - 旨在改进 AI 任务中关系推理的神经模块.</li></ul><h3 id="理论见解和原则性方法"><a href="#理论见解和原则性方法" class="headerlink" title="理论见解和原则性方法"></a>理论见解和原则性方法</h3><ul><li><a href="https://arxiv.org/abs/1511.06391?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Order Matters: Sequence to sequence for sets</a> - Investigating the impact of data order on model performance.<br> Order Matters: Sequence to sequence for sets - 调查数据顺序对模型性能的影响。</li><li><a href="https://arxiv.org/abs/2001.08361?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Scaling Laws for Neural LMs</a> - Empirical study on the scaling laws of language model performance.<br> Scaling Laws for Neural LMs -语言模型性能的缩放规律的实证研究.</li><li><a href="https://arxiv.org/abs/math/0406077?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">A Tutorial Introduction to the Minimum Description Length Principle</a> - Tutorial on the MDL principle in model selection and inference.<br> 最小描述长度原则教程简介 - 模型选择和推理中的MDL原理教程.</li><li><a href="https://www.cs.toronto.edu/~hinton/absps/colt93.pdf?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Keeping Neural Networks Simple by Minimizing the Description Length of the Weights</a> - Method to improve neural network generalization by minimizing weight description length.<br> 通过最小化权重的描述长度来保持神经网络的简单性 - 通过最小化权重描述长度来提高神经网络泛化的方法。</li><li><a href="https://pdfs.semanticscholar.org/e758/b579456545f8691bbadaf26bcd3b536c7172.pdf?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Machine Super Intelligence DissertationMachine Super Intelligence Dissertation</a> - Study on optimal behavior of agents in computable environments.<br> 机器 超级 智能 论文Machine Super Intelligence Dissertation - 研究智能体在可计算环境中的最优行为。</li><li><a href="https://www.lirmm.fr/~ashen/kolmbook-eng-scan.pdf?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">PAGE 434 onwards: Komogrov Complexity</a> - Comprehensive exploration of Kolmogorov complexity, discussing its mathematical foundations and implications for fields like information theory and computational complexity.<br> 第434页起:科莫格罗夫复杂性 - 全面探索柯尔莫戈罗夫复杂性,讨论其数学基础以及对信息论和计算复杂性等领域的影响。</li></ul><h3 id="跨学科和概念研究"><a href="#跨学科和概念研究" class="headerlink" title="跨学科和概念研究"></a>跨学科和概念研究</h3><ul><li><a href="https://arxiv.org/abs/1405.6903?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Quantifying the Rise and Fall of Complexity in Closed Systems: The Coffee Automaton</a> - Study on complexity in closed systems using cellular automata.<br> Quantifying the Rise and Fall of Complexity in Closed Systems: The Coffee Automaton - 使用元胞自动机研究封闭系统中的复杂性.</li></ul><h3 id="效率和可扩展性技术"><a href="#效率和可扩展性技术" class="headerlink" title="效率和可扩展性技术"></a>效率和可扩展性技术</h3><ul><li><a href="https://arxiv.org/abs/1811.06965?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">GPipe: Efficient Training of Giant Neural Networks using Pipeline Parallelism</a> - A method for efficient training of large-scale neural networks.<br> GPipe: Efficient Training of Giant Neural Networks using Pipeline Parallelism - 一种高效训练大规模神经网络的方法.</li></ul><h3 id="教材和教程"><a href="#教材和教程" class="headerlink" title="教材和教程"></a>教材和教程</h3><ul><li><a href="https://cs231n.github.io/?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">CS231n: Convolutional Neural Networks for Visual Recognition</a> - Stanford University course on CNNs for visual recognition.<br> CS231n:用于视觉识别的卷积神经网络 - 斯坦福大学视觉识别 CNN 课程。</li><li><a href="https://nlp.seas.harvard.edu/annotated-transformer/?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">The Annotated Transformer</a> - Annotated, line-by-line implementation of the Transformer paper. Code is available <a href="https://github.com/harvardnlp/annotated-transformer/?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">here</a>.<br> The Annotated Transformer - Transformer 论文的带注释的逐行实现.代码可在此处获得。</li><li><a href="https://scottaaronson.blog/?p=762&utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">The First Law of Complexodynamics</a> - Blog post discussing the measure of system complexity in computational terms.<br> The First Law of Complexodynamics - 讨论计算术语中系统复杂性度量的博客文章.</li><li><a href="https://karpathy.github.io/2015/05/21/rnn-effectiveness/?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">The Unreasonable Effectiveness of RNNs</a> - Blog post demonstrating the versatility of RNNs.<br> RNN 的不合理有效性 - 展示 RNN 多功能性的博客文章.</li><li><a href="https://colah.github.io/posts/2015-08-Understanding-LSTMs/?utm_source=www.turingpost.com&utm_medium=referral&utm_campaign=the-mysterious-ai-reading-list-ilya-sutskever-s-recommendations">Understanding LSTM Networks</a> - Blog post providing a detailed explanation of LSTM networks.<br> 了解 LSTM 网络 - 博客文章提供了 LSTM 网络的详细说明。</li></ul>]]></content>
<summary type="html"><ul>
<li><a href="#%E8%83%8C%E6%99%AF%E4%BB%8B%E7%BB%8D">背景介绍</a></li>
<li><a href="#%E4%B8%BB%E8%A6%81%E5%86%85%E5%AE%B9">主要内容</a><ul>
<li></summary>
</entry>
<entry>
<title>【随笔】关于个人成长的思考</title>
<link href="https://zade23.github.io/2024/05/10/%E3%80%90%E9%9A%8F%E7%AC%94%E3%80%91%E5%85%B3%E4%BA%8E%E4%B8%AA%E4%BA%BA%E6%88%90%E9%95%BF%E7%9A%84%E6%80%9D%E8%80%83/"/>
<id>https://zade23.github.io/2024/05/10/%E3%80%90%E9%9A%8F%E7%AC%94%E3%80%91%E5%85%B3%E4%BA%8E%E4%B8%AA%E4%BA%BA%E6%88%90%E9%95%BF%E7%9A%84%E6%80%9D%E8%80%83/</id>
<published>2024-05-10T03:05:52.000Z</published>
<updated>2024-05-10T07:26:17.273Z</updated>
<content type="html"><![CDATA[<p>标题相关内容未想好,就先空着吧。</p><p>本篇内容是一篇关于学习、成长、阶级跨越的思考……</p><p>起因是这一篇父亲写给女儿的信<a href="https://zhuanlan.zhihu.com/p/463715925">《阶层跨越》</a> 。</p><p>上一次阅读是在2022年,当时也正是因为这篇内容关注了作者。</p><p>就在昨天重新整理知乎关注的过程中,重新理解了一下这篇文章,感觉和上一次阅读有了完全不一样的体会。</p><p>上一次阅读的时候我还是研三在读,对于工作、领导、责任的感受不深。</p><p>现如今已经工作两年,对于之前不理解的内容和当时“感觉已经理解”的内容由有了不一样的体会。</p><p>也是。</p><p>屁股决定脑袋。</p><p>如果以后再看,可能还会有更不同的看法吧。</p><h2 id="观点陈述"><a href="#观点陈述" class="headerlink" title="观点陈述"></a>观点陈述</h2><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202405101125766.png" width="500" height="600"><p>得益于作者清晰的条理,AI总结的结果也非常清晰。</p><p>我通过这些年的经历结合上面提到的论点做出一些说明。</p><h3 id="情绪稳定"><a href="#情绪稳定" class="headerlink" title="情绪稳定"></a>情绪稳定</h3><p>人们常说的情绪稳定是面对打击和挫折时候的情绪。上面作者提到的“正确面对批评和挫折”,同样在今年黄仁勋于斯坦福的讲话中也举例自己年轻时候的端盘子经历以此来鼓励各位学子勇往直前锲而不舍。</p><p>我想说点和他们不同的,是我从自己身上找到的问题:乐极生悲</p><p>比如对于一些事情过度的期待。如果得不到成果还好,而如果得到了就会沾沾自喜和自己给自己思想放假(“这段时间我真辛苦,休息一下吧”),殊不知很多事情的成功伴随着团队/平台/导师等一些列因素。</p><p>这样的后果就是,每一次的小阶段成功之后会有一段时间的“产出真空期”,这是和我对自己设立的阶段目标严重不符的。</p><p>正确的做法应该是:理性客观的总结自己在事件和项目中的贡献,分析自己的改变,为什么可以做到这些改变,自己还有哪些不足并应该如何改正…………短暂的整理心情(平复心情)后,重新上路,追求下一个目标。</p><p>如范仲淹在《岳阳楼记》中所说:“不以物喜不以己悲”</p><h3 id="支持同事和领导"><a href="#支持同事和领导" class="headerlink" title="支持同事和领导"></a>支持同事和领导</h3><p>在研究生期间,导师给了我一个算法证明相关的课题。</p><p>众所周知,证明 + 算法。看似是非常高大上的课题,实则是枯燥乏味且很难获得成就感和反馈的,我很长一段时间都在枯燥的推公式和自我怀疑中度过,不可否认有一大部分的根源来自于能力不足。</p><p>在2019-2021年期间,正是AI相关应用爆发的时间段,也眼馋实验室别的同学随便蹭一蹭AI相关就能发文章的情况,就想找导师更换我自己的课题。</p><p>结果当然是失败了。</p><p>于是就开启了长达两年的纠结过程,做不爱做的课题,并且觉得导师太不通情达理了,自己开始做和课题无关的研究并且在宿舍摆烂(好孩子不要学)</p><p>现在想来,是自己在沟通和处理问题方面不成熟。</p><p>如果现在让重新和导师沟通,我会这么做:和导师商量一个关于该课题的最低标准(发几区、发几篇),然后表示出自己真正感兴趣的领域,并表面在该领域自己也可以发文章(这是沟通必要条件)。</p><p>当时做错的是逃避了沟通,在“负责任”和“支持领导”这两方面都没有成熟思考。</p><h3 id="口才和表达"><a href="#口才和表达" class="headerlink" title="口才和表达"></a>口才和表达</h3><p>再延伸一点,那就是:争取露脸机会</p><p>在高校和公司这样的地方,成熟的架构有成百上千号人,大佬们没有办法记住所有人。</p><p>最好的办法就是争取露脸机会。</p><p>争取到机会之后,勇敢去表现自己的能力和技术水准。</p><p>在技术人员中,有很大一部分的人是不太擅长表述的,他们的工程能力非常突出,但是表达的通常比较啰嗦。</p><p>前段时间听到过一个观点:人生就是一个巨大的推销过程。</p><p>做汇报、述职、做报告,其实就包含了推销自己的能力这个过程。</p><p>为什么在AI火爆的那段时间内,讲好故事的公司能够拿到融资,那是因为讲好故事就是一种“夸张”的推销表达。</p><p>未来希望自己可以培养的能力:<strong>口才</strong> + <strong>表达</strong> + <strong>把握机会的能力</strong></p><h3 id="做事能力和思维能力"><a href="#做事能力和思维能力" class="headerlink" title="做事能力和思维能力"></a>做事能力和思维能力</h3><p>做事能力:业务能力(基本) + 时间管理 + 团队合作(协作和沟通)</p><p>思维能力:超出当前层级的视角 + 学习领导能力</p><p>多年后重新看这篇文章,最区别的感受是要对于“整体架构”的把控。</p><p>原来自己觉得,只用把自己领域做大做强做精尖就可以了。</p><p>现在觉得这其实是很困难的,互联网的知识更新换代非常的快,永远学不完这个领域里所有的知识。</p><p>比较正确的做法应该是:掌握自己领域内最扎实的能力(业务能力) + 扩展知识的广度。</p><p>比如,要设计web端的AI应用,就需要了解前后端的相关技术,是否应该前后端分离,如果涉及到存储,数据库的选型应该是MySQL这种关系型数据库还是NoSQL类的非关系型数据库……对于上下游工作的了解能够让你和上下游更好的协调沟通(如果愿意的话,做个全栈也未尝不可)。</p><p>并且,对各方面技术栈的了解对于未来想做管理也是有帮助的。</p><p>待补充</p>]]></content>
<summary type="html"><p>标题相关内容未想好,就先空着吧。</p>
<p>本篇内容是一篇关于学习、成长、阶级跨越的思考……</p>
<p>起因是这一篇父亲写给女儿的信<a href="https://zhuanlan.zhihu.com/p/463715925">《阶层跨越》</a> 。</p>
<</summary>
</entry>
<entry>
<title>【Git】在README.md中展示视频的方案</title>
<link href="https://zade23.github.io/2024/04/26/%E3%80%90Git%E3%80%91%E5%9C%A8README-md%E4%B8%AD%E5%B1%95%E7%A4%BA%E8%A7%86%E9%A2%91%E7%9A%84%E6%96%B9%E6%A1%88/"/>
<id>https://zade23.github.io/2024/04/26/%E3%80%90Git%E3%80%91%E5%9C%A8README-md%E4%B8%AD%E5%B1%95%E7%A4%BA%E8%A7%86%E9%A2%91%E7%9A%84%E6%96%B9%E6%A1%88/</id>
<published>2024-04-26T03:53:42.000Z</published>
<updated>2024-04-26T03:58:20.162Z</updated>
<content type="html"><![CDATA[<ul><li><a href="#%E5%86%85%E5%AE%B9%E4%BB%8B%E7%BB%8D">内容介绍</a></li><li><a href="#%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E">使用说明</a><ul><li><a href="#github">github</a></li><li><a href="#gitlab">gitlab</a></li><li><a href="#blog%E6%94%AF%E6%8C%81%E7%9A%84html%E6%A0%BC%E5%BC%8F">blog支持的html格式</a></li></ul></li><li><a href="#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5">参考链接</a></li></ul><h2 id="内容介绍"><a href="#内容介绍" class="headerlink" title="内容介绍"></a>内容介绍</h2><p>在 GitHub 和 GitLab 仓库中,通过在 README.md 中展示视频Demo的方式直观的展示项目的效果。</p><p>最后,加上一种HTML形式渲染视频的方案,效果如下:</p><p><video src="https://github.com/zade23/zade23.github.io/assets/53324261/9ef0711b-29eb-4994-b34a-3d9d2152ea9b" controls="controls" width="500" height="300"></video></p><h2 id="使用说明"><a href="#使用说明" class="headerlink" title="使用说明"></a>使用说明</h2><h3 id="github"><a href="#github" class="headerlink" title="github"></a>github</h3><blockquote><p>注意:<strong>视频不能超过10m</strong></p></blockquote><p>GitHub 上用将视频提交到 issues 中,此时视频文件将上传到GitHub中并获得一个文件链接,这个链接放置在README中可以被直接渲染成视频。</p><ol><li>上传视频文件至某个 GitHub 项目的 issues 中</li><li>复制链接,放置在README中</li></ol><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202404261136499.jpg" alt="上传视频至issues"></p><h3 id="gitlab"><a href="#gitlab" class="headerlink" title="gitlab"></a>gitlab</h3><p>GitLab 可以直接用Markdown图片链接的格式渲染已存放在仓库或 issues 中的视频</p><ol><li>用图片链接的格式直接嵌入视频。<strong>支持格式为 <code>.mp4</code>、<code>.m4v</code>、<code>.mov</code>、<code>.webm</code> 和 <code>.ogv</code></strong></li><li>修改下面代码中视频文件的相对路径</li></ol><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Here's a sample video:</span><br><span class="line"></span><br><span class="line">![<span class="string">Sample Video</span>](<span class="link">img/markdown_video.mp4</span>)</span><br></pre></td></tr></table></figure><blockquote><p>嵌入链接同样可以是已经提到issues中的视频文件链接</p></blockquote><h3 id="blog支持的html格式"><a href="#blog支持的html格式" class="headerlink" title="blog支持的html格式"></a>blog支持的html格式</h3><p>先采用提issues的方式或者上传至仓库的方式将文件上传。</p><ol><li>将下面链接中 <code>src</code> 内的部分改成你的链接即可</li></ol><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">video</span> <span class="attr">src</span>=<span class="string">"movie.mp4.mp4"</span> <span class="attr">controls</span>=<span class="string">"controls"</span> <span class="attr">width</span>=<span class="string">"500"</span> <span class="attr">height</span>=<span class="string">"300"</span>></span><span class="tag"></<span class="name">video</span>></span></span><br></pre></td></tr></table></figure><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><ul><li><a href="https://docs.gitlab.cn/jh/user/markdown.html#%E8%A7%86%E9%A2%91">极狐文档中心-Markdown-视频</a></li><li><a href="http://t.csdnimg.cn/ehxyq">GitHub 仓库的 README 直接播放视频</a></li></ul>]]></content>
<summary type="html"><ul>
<li><a href="#%E5%86%85%E5%AE%B9%E4%BB%8B%E7%BB%8D">内容介绍</a></li>
<li><a href="#%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E">使用说明</a><ul>
<li></summary>
<category term="Git" scheme="https://zade23.github.io/tags/Git/"/>
</entry>
<entry>
<title>【Git】一个流畅的开源贡献流程</title>
<link href="https://zade23.github.io/2024/04/25/%E3%80%90Git%E3%80%91%E4%B8%80%E4%B8%AA%E6%B5%81%E7%95%85%E7%9A%84%E5%BC%80%E6%BA%90%E8%B4%A1%E7%8C%AE%E6%B5%81%E7%A8%8B/"/>
<id>https://zade23.github.io/2024/04/25/%E3%80%90Git%E3%80%91%E4%B8%80%E4%B8%AA%E6%B5%81%E7%95%85%E7%9A%84%E5%BC%80%E6%BA%90%E8%B4%A1%E7%8C%AE%E6%B5%81%E7%A8%8B/</id>
<published>2024-04-25T04:03:15.000Z</published>
<updated>2024-04-28T03:28:58.250Z</updated>
<content type="html"><![CDATA[<blockquote><p>由本人的有道云笔记搬运到个人网站,创作日期:2023年3月20日</p></blockquote><ul><li><a href="#%E6%95%99%E7%BB%83%E6%88%91%E6%83%B3%E5%BC%80%E6%BA%90">教练……我想开源</a></li><li><a href="#github%E5%BC%80%E6%BA%90%E4%BB%93%E5%BA%93%E5%B7%A5%E4%BD%9C%E6%B5%81">github开源仓库工作流</a></li><li><a href="#%E5%A6%82%E6%9E%9C%E6%88%91%E4%BB%AC%E6%83%B3%E8%BF%9B%E8%A1%8C%E5%BC%80%E6%BA%90%E8%B4%A1%E7%8C%AE">如果我们想进行开源贡献</a></li><li><a href="#paddle%E9%A1%B9%E7%9B%AE">Paddle项目</a><ul><li><a href="#%E6%96%87%E6%A1%A3%E8%B4%A1%E7%8C%AE%E6%8C%87%E5%8D%97">文档贡献指南</a><ul><li><a href="#%E7%AC%AC%E4%B8%80%E6%AD%A5fork%E4%BB%93%E5%BA%93%E5%B9%B6clone%E5%88%B0%E6%9C%AC%E5%9C%B0%E5%8A%A0%E8%BD%BD">第一步:Fork仓库并Clone到本地加载</a></li><li><a href="#%E7%AC%AC%E4%BA%8C%E6%AD%A5fork%E4%BB%93%E5%BA%93%E5%B9%B6clone%E5%88%B0%E6%9C%AC%E5%9C%B0%E5%8A%A0%E8%BD%BD">第二步:Fork仓库并Clone到本地加载</a></li><li><a href="#%E7%AC%AC%E4%B8%89%E6%AD%A5%E4%B8%8B%E8%BD%BDpre-commit%E5%B7%A5%E5%85%B7%E4%B8%8B%E8%BD%BD%E8%BF%87%E5%B0%B1%E4%B8%8D%E7%94%A8%E5%86%8D%E4%B8%8B%E4%BA%86">第三步:下载pre-commit工具(下载过就不用再下了)</a></li><li><a href="#%E7%AC%AC%E5%9B%9B%E6%AD%A5%E5%8D%95%E6%AC%A1%E4%BF%AE%E6%94%B9%E5%B9%B6%E6%8F%90%E4%BA%A4%E9%83%BD%E8%A6%81%E8%BF%90%E8%A1%8Cpre-commit%E8%BF%9B%E8%A1%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95">第四步:单次修改并提交都要运行pre-commit进行单元测试</a><ul><li><a href="#%E6%8F%90%E4%BA%A4commit">提交:commit</a></li></ul></li><li><a href="#%E7%AC%AC%E4%BA%94%E6%AD%A5push">第五步:push</a></li><li><a href="#%E7%AC%AC%E5%85%AD%E6%AD%A5review--merge">第六步:review & merge</a></li><li><a href="#%E5%B0%8F%E6%8F%92%E6%9B%B2checkprtemplate-%E4%B8%80%E5%AE%9A%E8%A6%81%E8%A7%84%E8%8C%83">小插曲:CheckPRTemplate 一定要规范</a></li></ul></li></ul></li><li><a href="#gradio%E9%A1%B9%E7%9B%AE">Gradio项目</a></li><li><a href="#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5">参考链接</a></li></ul><h2 id="教练……我想开源"><a href="#教练……我想开源" class="headerlink" title="教练……我想开源"></a>教练……我想开源</h2><p>一直想参加一个开源项目,丰富自己GitHub账号头衔的同时还能学到一些知识。目前定位到了两个自己非常感兴趣的项目</p><ol><li>(国内项目)Paddle:百度飞桨深度学习框架</li><li>(国际项目)Gradio:用Python构建机器学习网页APP<br>在项目主页的 Issues 提出自己的问题</li></ol><h2 id="github开源仓库工作流"><a href="#github开源仓库工作流" class="headerlink" title="github开源仓库工作流"></a>github开源仓库工作流</h2><blockquote><p>参考<a href="https://nvie.com/posts/a-successful-git-branching-model/">《A successful Git branching model》</a><br>Remote(main/):所有人都共享的代码仓库</p></blockquote><h2 id="如果我们想进行开源贡献"><a href="#如果我们想进行开源贡献" class="headerlink" title="如果我们想进行开源贡献"></a>如果我们想进行开源贡献</h2><ul><li>第一步就是建立一个“feature branch”。目前在Local上,main branch 和 feature branch 上面的内容都是一致的。当使用checkout命令后,硬盘会同步git指定branch下所有的源文件(切换就会改变硬盘当下空间内部的文件)<br>如何正确提Issues<br> 在提Issues之前,一定要提前用关键字搜索看一下你想提出的问题是否已经存在。确定不存在后再进行提问</li></ul><h2 id="Paddle项目"><a href="#Paddle项目" class="headerlink" title="Paddle项目"></a>Paddle项目</h2><h3 id="文档贡献指南"><a href="#文档贡献指南" class="headerlink" title="文档贡献指南"></a>文档贡献指南</h3><p>以最近的一次合并提交为例:本次提交是添加了Tensor文件夹下的十个说明文档。</p><h4 id="第一步:Fork仓库并Clone到本地加载"><a href="#第一步:Fork仓库并Clone到本地加载" class="headerlink" title="第一步:Fork仓库并Clone到本地加载"></a>第一步:Fork仓库并Clone到本地加载</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/<USERNAME>/docs</span><br><span class="line"><span class="built_in">cd</span> docs</span><br></pre></td></tr></table></figure><h4 id="第二步:Fork仓库并Clone到本地加载"><a href="#第二步:Fork仓库并Clone到本地加载" class="headerlink" title="第二步:Fork仓库并Clone到本地加载"></a>第二步:Fork仓库并Clone到本地加载</h4><p>docs 目前使用 Git 流分支模型进行开发,测试,发行和维护。<br>所有的 feature 和 bug fix 的开发工作都应该在一个新的分支上完成,一般从 develop 分支上创建新分支。<br>使用 <code>git checkout -b</code> 创建并切换到新分支。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git status <span class="comment">#查看一下当前分支目录是否clean</span></span><br><span class="line">git checkout -b <创建并切换到的分支名称></span><br></pre></td></tr></table></figure><h4 id="第三步:下载pre-commit工具(下载过就不用再下了)"><a href="#第三步:下载pre-commit工具(下载过就不用再下了)" class="headerlink" title="第三步:下载pre-commit工具(下载过就不用再下了)"></a>第三步:下载pre-commit工具(下载过就不用再下了)</h4><p>一种检查模板格式是否匹配项目格式的预提交工具。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pip install pre-commit</span><br><span class="line">pre-commit install</span><br></pre></td></tr></table></figure><h4 id="第四步:单次修改并提交都要运行pre-commit进行单元测试"><a href="#第四步:单次修改并提交都要运行pre-commit进行单元测试" class="headerlink" title="第四步:单次修改并提交都要运行pre-commit进行单元测试"></a>第四步:单次修改并提交都要运行pre-commit进行单元测试</h4><ol><li>通过指令 git status 进行状态的检查</li><li>通过 git add 将内容添加进准备提交的区域</li></ol><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/1714027390144.jpg" alt="git status"></p><blockquote><p>上面的状态空间中显示我 9 次修改中有 1 次进入了“暂存区”,此时就要使用pre-commit指令进行单元测试</p></blockquote><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/1714027493043.jpg" alt="pre-commit"></p><blockquote><p>上面在运行了pre-commit之后,除了红色以外区域显示是通过的部分。红色部分说明没有通过单元测试,这个报错说明Linux系统和Win系统的换行符不统一导致的格式问题,一般这种情况下pre-commit会自己进行修复,所以重新提交就可以解决</p></blockquote><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/1714027499063.jpg" alt="pre-commit"></p><blockquote><p>上面在进行了一次性的提交之后,pre-commit一次性将所有的文件进行了检查和修改,之后再进行一次 git add –update 就可以将更新修改后的文件合并至文件的缓存区内。</p></blockquote><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202404251451164.jpg" alt="git add --update"></p><blockquote><p>解决步骤如上</p></blockquote><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202404251451889.jpg" alt="pre-commit"></p><blockquote><p>在进行一次提交之后就可以看到所有单元测试已经通过了</p></blockquote><p>在单元测试全部通过之后,可以正式填写提交说明了:</p><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202404251452892.jpg" alt="git commit"></p><blockquote><p>上面我提出的说明是“修改文档”。显示有 9 个文件被修改了, 20 行新增代码, 22 行删减代码。</p></blockquote><h5 id="提交:commit"><a href="#提交:commit" class="headerlink" title="提交:commit"></a>提交:commit</h5><p><strong>之所以要运行 <code>pre-commit</code> 就是要为后面要执行的commit操作避免提前的冲突和麻烦</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git commit -m <span class="string">"fix/add xxxx"</span></span><br></pre></td></tr></table></figure><h4 id="第五步:push"><a href="#第五步:push" class="headerlink" title="第五步:push"></a>第五步:push</h4><p>先确保已经同步过原始仓库的最新代码 <a href="https://github.com/PaddlePaddle/docs">https://github.com/PaddlePaddle/docs</a></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">➜ git remote</span><br><span class="line">origin</span><br><span class="line">➜ git remote -v</span><br><span class="line">origin https://github.com/USERNAME/docs (fetch)</span><br><span class="line">origin https://github.com/USERNAME/docs (push)</span><br><span class="line"></span><br><span class="line"><span class="comment"># origin 是 clone 的远程仓库的名字,也就是自己用户名下的 Paddle,接下来创建一个原始 Paddle 的仓库远程主机,命名为 upstream</span></span><br><span class="line">➜ git remote add upstream https://github.com/PaddlePaddle/docs</span><br><span class="line">➜ git remote</span><br><span class="line">>> origin</span><br><span class="line">>> upstream</span><br><span class="line">-----------------------------------之前提交过了就可以跳到这一步---------------------------------------------</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取 upstream 的最新代码并更新当前分支</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 从 upstream 远程仓库获取最新的代码和提交历史,将本地仓库与远程仓库保持同步。</span></span><br><span class="line">➜ git fetch upstream </span><br><span class="line"></span><br><span class="line"><span class="comment"># 从 upstream 远程仓库 develop 分支中获取最新的代码和提交历史,并将其自动合并到当前本地分支。</span></span><br><span class="line">➜ git pull upstream develop </span><br><span class="line"></span><br><span class="line"><span class="comment"># Push 到远程仓库:也就是将本地修改推送到 GitHub 即: https://github.com/USERNAME/docs</span></span><br><span class="line"><span class="comment"># 将本地分支的提交推送到名为origin的远程仓库中的特定分支(<my-pr>)。</span></span><br><span class="line"><span class="comment"># 通过执行此命令,您可以将本地分支的修改上传到远程仓库,使得其他协作者可以查看和访问您的提交。</span></span><br><span class="line">➜ git push origin <my-pr(第二步中取的名字)></span><br></pre></td></tr></table></figure><h4 id="第六步:review-amp-merge"><a href="#第六步:review-amp-merge" class="headerlink" title="第六步:review & merge"></a>第六步:review & merge</h4><blockquote><p>我的第一次提交 <a href="https://github.com/PaddlePaddle/docs/pull/5747">https://github.com/PaddlePaddle/docs/pull/5747</a><br>几点小的总结:</p></blockquote><ul><li>尽量把自己在做的过程中不确定的内容进行说明</li><li>把疑问的地方进行复现</li><li>每一轮的回复都要进行礼貌性的回答</li><li>尽量把每一版的修改都进行分点的说明,第一做了XXX,第二做了XXXX……</li><li></li></ul><h4 id="小插曲:CheckPRTemplate-一定要规范"><a href="#小插曲:CheckPRTemplate-一定要规范" class="headerlink" title="小插曲:CheckPRTemplate 一定要规范"></a>小插曲:CheckPRTemplate 一定要规范</h4><p>如果希望 Paddle 能够接受你的提交,至少需要满足以下三点:</p><ul><li><p>单元测试通过 —— Docs-NEW</p></li><li><p>文档PR格式检测通过 —— CheckPRTemplate</p></li><li><p>同意签署开源贡献者协议 —— license/cla<br>一般Docs-NEW可能需要比较长的时间进行检测,偶尔也需要排队等待。所以这次我以为 CheckPRTemplat 也是一样需要等,但是等了整整一天时间……最后发现其实PR格式不是特别正确(虽然也有人格式不正确但通过了PR格式检测),最终参考 <a href="https://www.paddlepaddle.org.cn/documentation/docs/zh/dev_guides/git_guides/paddle_ci_manual_cn.html#checkprtemplate">checkprtemplate</a> 。修改后的格式如下:</p><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202404251453294.jpg" alt="Paddle项目开源贡献要求的格式"></p></li></ul><p>修改之后秒过。</p><h2 id="Gradio项目"><a href="#Gradio项目" class="headerlink" title="Gradio项目"></a>Gradio项目</h2><p>一位同学进行的一个非常标准的开源参与流程:</p><ol><li><p>提Issues。在这个过程中以项目管理者角度出发,顺带说明了四点问题:</p><ol><li><strong>是否已存在类似Issue。</strong>I have searched to see if a similar issue already exists.(我已经搜索过是否已经存在类似问题。)</li><li><strong>描述你的问题和想添加的功能。</strong>Is your feature request related to a problem? Please describe.(您的功能请求是否与问题相关?请描述。)</li><li><strong>提出解决方案。</strong>Describe the solution you’d like.(描述您想要的解决方案)</li><li><strong>是否有前情提要。</strong>Additional context.(附加上下文)</li></ol><p> <img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202404251453976.jpg" alt="提问动机"></p></li><li><p>请求合并Merge。在这个过程中以项目管理者角度出发,顺带说明了四点问题:</p><ol><li>relevant motivation.(相关动机)</li><li>a summary of the change.(总结你做出的更改)</li><li>which issue is fixed.(解决了Issue中的哪一个)</li><li>any additional dependencies that are required for this change.(在本次变更中是否有其他依赖项)</li></ol><p> <img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/202404251454853.jpg" alt="详细描述自己所做的工作"></p></li></ol><hr><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><ol><li><p>git commit之后,想撤销commit</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git reset --soft HEAD^</span><br></pre></td></tr></table></figure></li><li><p>视频链接</p><ol><li><a href="https://www.bilibili.com/video/BV18T411z7R4/?share_source=copy_web&vd_source=48383e849d4fc23ac2e38278a3df1b87">【如何正确地提github issue?开源项目作者来和你聊聊这个重要技能】</a></li><li><a href="https://www.bilibili.com/video/BV19e4y1q7JJ/?share_source=copy_web&vd_source=48383e849d4fc23ac2e38278a3df1b87">【十分钟学会正确的github工作流,和开源作者们使用同一套流程】</a></li><li><a href="https://www.freecodecamp.org/chinese/news/how-to-make-your-first-pull-request-on-github/">【freeCodeCamp | 如何在 GitHub 提交第一个 pull request】</a></li></ol></li><li><p>AIstudio上持久化安装pip包</p><ol><li>提前运行 <code>cd ~ && mkdir loca_data && ln -s local_data.local</code></li></ol></li><li><p><a href="https://www.bilibili.com/video/BV19e4y1q7JJ/?share_source=copy_web&vd_source=48383e849d4fc23ac2e38278a3df1b87">十分钟学会正确的github工作流,和开源作者们使用同一套流程</a></p><blockquote><p>一套开源项目和部分企业都在使用的工作流</p></blockquote></li></ol>]]></content>
<summary type="html"><blockquote>
<p>由本人的有道云笔记搬运到个人网站,创作日期:2023年3月20日</p>
</blockquote>
<ul>
<li><a href="#%E6%95%99%E7%BB%83%E6%88%91%E6%83%B3%E5%BC%80%E6%BA%90</summary>
<category term="Git Workflow" scheme="https://zade23.github.io/categories/Git-Workflow/"/>
<category term="Git" scheme="https://zade23.github.io/tags/Git/"/>
</entry>
<entry>
<title>【Unity】破解版安装指北</title>
<link href="https://zade23.github.io/2024/04/22/%E3%80%90Unity%E3%80%91%E7%A0%B4%E8%A7%A3%E7%89%88%E5%AE%89%E8%A3%85%E6%8C%87%E5%8C%97/"/>
<id>https://zade23.github.io/2024/04/22/%E3%80%90Unity%E3%80%91%E7%A0%B4%E8%A7%A3%E7%89%88%E5%AE%89%E8%A3%85%E6%8C%87%E5%8C%97/</id>
<published>2024-04-22T13:27:41.000Z</published>
<updated>2024-04-22T13:42:52.171Z</updated>
<content type="html"><![CDATA[<ul><li><a href="#%E4%BB%8B%E7%BB%8D">介绍</a></li><li><a href="#%E7%89%88%E6%9C%AC%E9%80%89%E6%8B%A9">版本选择</a></li><li><a href="#%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E">使用说明</a></li><li><a href="#%E8%B8%A9%E5%9D%91">踩坑</a></li></ul><h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><p>个人版的Unity安装通过Unity官网一步一步进行即可。<br>今天我们聊的是:如何安装Unity的完整破解版。</p><p>如果没有许可的Unity项目在重新登录之后会提示如下界面:<br><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/A3c6EYT72l.jpg" alt="没有许可"></p><p>在这个状态下,左右两个选项都无法正常启动项目,那么就需要考虑使用个人版或者破解Unity了。</p><blockquote><p>注意:以下内容仅供用于非营利性的教育和测试目的。</p></blockquote><h2 id="版本选择"><a href="#版本选择" class="headerlink" title="版本选择"></a>版本选择</h2><p>我当前使用的版本参数如下:</p><ul><li>Unity:2022.3.9f1</li><li>Unity Hub:3.4.2</li></ul><p>关于Unity破解版这里用到以下两个用于破解软件的链接:</p><ul><li><a href="https://github.com/tylearymf/UniHacker">https://github.com/tylearymf/UniHacker</a></li><li><a href="https://github.com/agentbillwh/unilic">https://github.com/agentbillwh/unilic</a></li></ul><p>两个GitHub工程的对应Unity项目的破解关系是:</p><p><strong>UniHacker → Unity Hub</strong><br><strong>unilic → Unity</strong></p><p>正常情况下UniHacker可以同时破解 Unity 和 Unity Hub,由于UniHacker可以破解的Unity版本不能高于2022.2所以我们另外使用unilic破解Unity。</p><p>这样破解就可以使用较新的Unity版本了。</p><h2 id="使用说明"><a href="#使用说明" class="headerlink" title="使用说明"></a>使用说明</h2><p>上述链接中的两个工程都是非常详细的工程,按照<code>READ.md</code>内容一步一步来即可,UniHacker更是打包成了一个<code>.exe</code>文件供用户直接破解。</p><p>UniHacker的破解结束后有两个选项:</p><ul><li>是否登录自己的账号:建议<code>否</code></li><li>是否保持更新:建议<code>否</code></li></ul><p>破解成功后,可打开原始项目。<br><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/img_v3_02a6_ede5a60a-bb44-416f-830e-e3843209257g.jpg" alt="Unity,启动"></p><h2 id="踩坑"><a href="#踩坑" class="headerlink" title="踩坑"></a>踩坑</h2><ol><li><p>Unity Hub 版本不能太高</p><p> 如果只破解了Unity而没有破解Unity Hub(或Unity Hub的版本过高,如图中3.7版)则会在打开项目的时候反复弹窗确认登录信息。</p></li></ol><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/img_v3_02a6_71156aec-81f4-4cef-80d0-a9f51738028g.jpg" alt="版本过高"></p>]]></content>
<summary type="html"><ul>
<li><a href="#%E4%BB%8B%E7%BB%8D">介绍</a></li>
<li><a href="#%E7%89%88%E6%9C%AC%E9%80%89%E6%8B%A9">版本选择</a></li>
<li><a href="#%E4%BD%BF</summary>
<category term="Unity" scheme="https://zade23.github.io/categories/Unity/"/>
<category term="Game Engine" scheme="https://zade23.github.io/tags/Game-Engine/"/>
</entry>
<entry>
<title>【NLP】RWKV对比Transformer</title>
<link href="https://zade23.github.io/2024/04/16/%E3%80%90NLP%E3%80%91RWKV%E5%AF%B9%E6%AF%94Transformer/"/>
<id>https://zade23.github.io/2024/04/16/%E3%80%90NLP%E3%80%91RWKV%E5%AF%B9%E6%AF%94Transformer/</id>
<published>2024-04-16T03:25:31.000Z</published>
<updated>2024-04-16T09:01:32.603Z</updated>
<content type="html"><![CDATA[<h3 id="模型的精度问题"><a href="#模型的精度问题" class="headerlink" title="模型的精度问题"></a>模型的精度问题</h3><p>int4? int8? bf16? bf32? float16? float32?</p><h3 id="模型参数文件"><a href="#模型参数文件" class="headerlink" title="模型参数文件"></a>模型参数文件</h3><p>常见的 <code>generation_config.json</code> 文件</p><p>下面的内容来自 Baichuan2-7B-Chat 模型生成器参数文件</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"pad_token_id"</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"bos_token_id"</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"eos_token_id"</span><span class="punctuation">:</span> <span class="number">2</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"user_token_id"</span><span class="punctuation">:</span> <span class="number">195</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"assistant_token_id"</span><span class="punctuation">:</span> <span class="number">196</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"max_new_tokens"</span><span class="punctuation">:</span> <span class="number">2048</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"temperature"</span><span class="punctuation">:</span> <span class="number">0.3</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"top_k"</span><span class="punctuation">:</span> <span class="number">5</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"top_p"</span><span class="punctuation">:</span> <span class="number">0.85</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"repetition_penalty"</span><span class="punctuation">:</span> <span class="number">1.05</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"do_sample"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"transformers_version"</span><span class="punctuation">:</span> <span class="string">"4.29.2"</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><p>下面的内容来自 <code>RWKV/v5-Eagle-7B-HF</code> 模型生成器参数文件</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"chat_format"</span><span class="punctuation">:</span> <span class="string">"chatml"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"eos_token_id"</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"pad_token_id"</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"max_window_size"</span><span class="punctuation">:</span> <span class="number">4096</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"max_new_tokens"</span><span class="punctuation">:</span> <span class="number">4096</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"do_sample"</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"top_k"</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"top_p"</span><span class="punctuation">:</span> <span class="number">0.1</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"repetition_penalty"</span><span class="punctuation">:</span> <span class="number">1.0</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"transformers_version"</span><span class="punctuation">:</span> <span class="string">"4.31.1"</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><h3 id="半精度?全精度?-指令微调?-chat模型?"><a href="#半精度?全精度?-指令微调?-chat模型?" class="headerlink" title="半精度?全精度? 指令微调? chat模型?"></a>半精度?全精度? 指令微调? chat模型?</h3><p>HF模型?</p><h3 id="微调方式"><a href="#微调方式" class="headerlink" title="微调方式"></a>微调方式</h3><p>指令微调?全量/半精度/零样本?</p>]]></content>
<summary type="html"><h3 id="模型的精度问题"><a href="#模型的精度问题" class="headerlink" title="模型的精度问题"></a>模型的精度问题</h3><p>int4? int8? bf16? bf32? float16? float32?</p>
<h3 </summary>
</entry>
<entry>
<title>【NLP】RWKV框架入门</title>
<link href="https://zade23.github.io/2024/04/15/%E3%80%90NLP%E3%80%91RWKV%E6%A1%86%E6%9E%B6%E5%85%A5%E9%97%A8/"/>
<id>https://zade23.github.io/2024/04/15/%E3%80%90NLP%E3%80%91RWKV%E6%A1%86%E6%9E%B6%E5%85%A5%E9%97%A8/</id>
<published>2024-04-15T03:56:48.000Z</published>
<updated>2024-04-25T07:00:53.080Z</updated>
<content type="html"><![CDATA[<p>全文从以下几个方面展开:</p><ul><li><a href="#rwkv%E6%98%AF%E4%BB%80%E4%B9%88">RWKV是什么</a><ul><li><a href="#%E6%9E%B6%E6%9E%84%E7%BB%84%E6%88%90">架构组成</a></li><li><a href="#%E7%89%B9%E6%AE%8A%E6%80%A7%E5%88%86%E6%9E%90">特殊性分析</a></li></ul></li><li><a href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E9%80%89%E5%9E%8Brwkv%E5%81%9A%E5%A4%A7%E8%AF%AD%E8%A8%80%E5%9F%BA%E5%BA%95%E6%A8%A1%E5%9E%8B%E7%9A%84%E9%A2%84%E7%A0%94">为什么选型RWKV做大语言基底模型的预研</a></li><li><a href="#rwkv%E5%92%8Ctransformer%E7%9A%84%E5%B7%AE%E5%88%AB">RWKV和Transformer的差别</a></li><li><a href="#%E7%BB%93%E6%9E%84%E5%BB%BA%E6%A8%A1">结构建模</a><ul><li><a href="#self-attention">Self-Attention</a></li><li><a href="#multi-head-attention">Multi-Head Attention</a></li><li><a href="#rwkv%E7%BB%93%E6%9E%84">RWKV结构</a></li><li><a href="#%E6%95%88%E6%9E%9C%E8%A1%A8%E7%8E%B07b">效果表现(7B)</a></li><li><a href="#%E7%BB%93%E8%AF%AD">结语</a></li></ul></li></ul><hr><h2 id="RWKV是什么"><a href="#RWKV是什么" class="headerlink" title="RWKV是什么"></a>RWKV是什么</h2><p>RWKV架构是一种针对分布式存储系统的架构设计,主要关注于提高数据的可靠性、可用性和一致性,同时优化性能和扩展性。</p><p>RWKV代表的是Read-Write-Key-Value,这个架构通过分离读(R)和写(W)操作,以及将键(Key)和值(Value)分离,来实现其设计目标。</p><h3 id="架构组成"><a href="#架构组成" class="headerlink" title="架构组成"></a>架构组成</h3><ol><li><strong>读写分离</strong>:RWKV架构中,<strong>读操作</strong> 和 <strong>写操作</strong> 是分开处理的。这意味着系统可以针对读操作进行优化,比如通过缓存机制来提高读取速度,而写操作则可以专注于数据的持久化和一致性保证。</li><li><strong>键值存储</strong>:在这种架构中,键(Key)和值(Value)是分开存储的。键通常包含了定位数据所需的全部信息,而值则是实际的数据内容。这种分离使得系统可以更加灵活地管理数据,比如可以实现键的索引,从而加快查找速度。</li><li><strong>数据分区</strong>:为了提高系统的扩展性,RWKV架构通常会将数据进行分区。每个分区可以独立地进行读写操作,这样可以在不影响整个系统的情况下,对单个分区进行扩展或维护。</li></ol><h3 id="特殊性分析"><a href="#特殊性分析" class="headerlink" title="特殊性分析"></a>特殊性分析</h3><ol><li><strong>高性能</strong>:通过读写分离,RWKV架构能够针对不同的操作类型进行专门的优化。例如,读操作可以通过增加缓存层来提高响应速度,而写操作则可以通过批量处理和日志优化来提高吞吐量。</li><li><strong>高可用性</strong>:RWKV架构通过数据分区和副本机制来保证数据的可用性。即使某个分区发生故障,系统也可以通过其他分区或副本来继续提供服务。</li><li><strong>一致性保证</strong>:在分布式系统中,数据一致性是一个重要的问题。RWKV架构通过写操作的严格控制和一致性协议,比如两阶段提交(2PC)或Paxos、Raft等算法,来确保数据在多个副本之间的一致性。</li><li><strong>扩展性</strong>:由于数据分区的设计,RWKV架构可以很好地支持水平扩展。当系统需要处理更多的数据或请求时,可以通过增加更多的分区来实现。</li><li><strong>灵活性</strong>:键值分离的设计使得RWKV架构在数据管理上具有很高的灵活性。可以根据业务需求,对键进行定制化的索引和查询,从而更好地支持复杂的应用场景。</li></ol><h2 id="为什么选型RWKV做大语言基底模型的预研"><a href="#为什么选型RWKV做大语言基底模型的预研" class="headerlink" title="为什么选型RWKV做大语言基底模型的预研"></a>为什么选型RWKV做大语言基底模型的预研</h2><p>因为:便宜好用(这里的便宜是指算力的便宜)</p><p>到底有多便宜呢?</p><p>上图是RWKV架构模型对比Transformer类架构模型在完成推理任务时的时间复杂度和空间复杂度对比。</p><p>通过复杂度可以看到,RWKV架构模型推理的耗时和内存占用随Tokens(可以简单理解为字数)长度呈线性增长关系。而Transformer类模型则呈幂级数增长关系,如果表现在游戏对话任务中,就是和NPC说的话越多,它回复你的时间就会越久,这也很贴合Transformer模型中的重要结构Attention机制的中文翻译——“注意力”。</p><p>前些日子看到有文章说华为内部开始研究RWKV架构去服务于他们的大语言模型,于是去其官网上一探究竟,发现 <a href="https://stability.ai/">stability.ai</a>(开源AI绘画架构的开发公司)也对RWKV进行了赞助,说明RWKV在架构一定有它的特殊性和优越性,于是决定研究一下。</p><p>早在2023年5月RWKV架构问世就已经,在一众Transformer模型架构的LLM领域下,这是一个使用RNN架构进行模型推理的模型。并且在竞争激烈的大语言模型评测中排到了第八名的成绩。</p><p>长话短说,如果使用RWKV,最希望它能够解决的问题是:<strong>费用问题</strong></p><p>在某上线项目的用户信息采集中,我们发现:玩家其实并不那么care游戏中的AI智不智能(更多的是来看看这个AI是不是一个噱头),也并没有对于它不能回答自己的奇怪提问而提出不满(注意:这里得到的结果并不具有泛化性,有许多影响这一结果的因素没有考虑,包括但不限于:游戏玩法和用户年龄段画像等)。那么在学术界上的细扣模型智能面板上提升零点几个百分点的性能表现大战就几乎不需要考虑了,与其牺牲更多的开发成本和模型加载成本得到一个智力刚及格的AI,还要被玩家拷打“爸爸的爸爸叫什么~”,不如创造一个弱智吧吧友级别的AI更有节目效果。</p><h2 id="RWKV和Transformer的差别"><a href="#RWKV和Transformer的差别" class="headerlink" title="RWKV和Transformer的差别"></a>RWKV和Transformer的差别</h2><p>RWKV相较于Transformer:</p><p>优点(便宜)</p><ul><li>在训练和推理中更少的资源占用(VRAM,CPU, GPU,etc)</li><li>对比长上下文的Transformer架构大语言模型,计算要求降低了<strong>10到100倍</strong></li><li>可以线性缩放到任意长度的上下文(在时间复杂度上Transformer架构的时间复杂度是O(n) )</li><li>RWKV通常在这几类语言(例如中文、日语等)上训练的更好,然后才是其他开源的LLM模型</li></ul><p>缺点(对提示词的要求高)</p><ul><li>对提示词的要求更高,需要用户提出详细描述的问题</li><li>在需要回顾的任务上表现较弱,因此需要相应地重新排序提示词的顺序<ul><li>(正例:“阅读下面的文档,帮我执行XX任务。文档为……” √)</li><li>(反例(回顾任务):“对于上面一段对话中的内容,帮我执行XX任务。” ×)</li></ul></li></ul><blockquote><p>以上优缺点对比来自RWKV官网:<a href="https://wiki.rwkv.com/#tldr-vs-existing-transformer-models">https://wiki.rwkv.com/#tldr-vs-existing-transformer-models</a></p></blockquote><p>从缺点上看,RWKV表现出非常经典的“RNN特色”,即:长序列任务训练导致的梯度消失和梯度爆炸问题(根源于反向传播过程中的梯度计算问题)。但是其实没有特别想清楚为什么训练阶段的问题会推广至推理阶段。</p><p>看到这里,方便给对于AI领域的专业名词不那么了解的同学讲清楚这个性能侧重问题,我假设衡量大语言模型的性能有以下四个维度:适用领域——多、推理速度——快、表现效果——好、内存占用——省,可绘制的表格如下:</p><table><thead><tr><th></th><th>适用领域</th><th>推理速度</th><th>表现效果</th><th>内存占用</th></tr></thead><tbody><tr><td>Transformer</td><td>多(Attention is ALL you need)</td><td>慢(O(n2))</td><td>好(或许应该听过Sora是Transformer架构结合Diffusion实现的)</td><td>慢(O(n2))</td></tr><tr><td>RWKV</td><td>较多(RWKV-Runner中可以看到AI绘画和音乐生成等工作)</td><td>快(O(n))</td><td>一般(源自于自身结构的脆弱性,在长序列下的表现有时像一个健忘的老人,类似于下面这种表现:input:马冬梅 → output:马冬什么/马什么梅/什么冬梅)</td><td>快(O(n))</td></tr></tbody></table><p>这样一个简单的性能矩阵关系,我们应该可以大概定义Transformer和RWKV的应用场景:</p><ul><li>Transformer侧重于整体性能的表现效果,如果在高并发的场景下使用将非常非常吃服务器性能和配置。如果使用Transformer作为底层模型架构启动AI相关服务,要么提升显卡算力性能,要么对模型进行剪枝蒸馏等一些列模型压缩工作。</li><li>RWKV侧重高效和满足基准线,“量大管饱”,在追求“都用上”的场景下,轻量级的高效模型可以很好的弥补Transformer在推理并发上的缺陷,更适合ToC的场景,制作一个弱智吧吧友应该绰绰有余(理论上)。</li></ul><h2 id="结构建模"><a href="#结构建模" class="headerlink" title="结构建模"></a>结构建模</h2><h3 id="Self-Attention"><a href="#Self-Attention" class="headerlink" title="Self-Attention"></a>Self-Attention</h3><p>一个简单的自注意力机制的实现。</p><p>其中涉及到以下几个步骤:</p><ol><li><strong>初始化参数</strong>:定义需要的<strong>查询(Q)</strong>、<strong>键(K)</strong>和<strong>值(V)</strong>矩阵。</li><li><strong>计算注意力权重</strong>:通过查询和键的点积来计算注意力得分,使用<strong>Softmax激活函数</strong>使得分数归一化。</li><li><strong>计算输出</strong>:使用得到的注意力权重对值进行加权求和。</li></ol><p>假设输入是一个小批量的嵌入向量,每个向量维度一致。</p><p>下面仅用 Python 语言和 NumPy 库来实现一个基本的自注意力结构。</p><p>首先,导入必要的库,其次定义一些参数和初始化权重。接下来是关键的一步,创建一个自注意力层,其中输入、查询、键、值的维度都是相同的。</p><p>假设批量大小为一个简单的例子,并处理几个向量。</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 导入库函数 NumPy</span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="comment"># 利用 NumPy 来写 Softmax 激活函数(也可以使用torch中现成的)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">softmax</span>(<span class="params">x</span>):</span><br><span class="line"> e_x = np.exp(x - np.<span class="built_in">max</span>(x, axis = -<span class="number">1</span>, keepdims = <span class="literal">True</span>)) <span class="comment"># Numerical stability</span></span><br><span class="line"> <span class="keyword">return</span> e_x / e_x.<span class="built_in">sum</span>(axis = -<span class="number">1</span>, keepdims = <span class="literal">True</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">SelfAttention</span>:</span><br><span class="line"> <span class="comment"># 权重随机初始化</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, embed_size</span>):</span><br><span class="line"> self.embed_size = embed_size</span><br><span class="line"> <span class="comment"># 初始化权重矩阵。简单起见,我们使用**随机初始化**</span></span><br><span class="line"> self.query_weights = np.random.rand(embed_size, embed_size)</span><br><span class="line"> self.key_weights = np.random.rand(embed_size, embed_size)</span><br><span class="line"> self.value_weights = np.random.rand(embed_size, embed_size)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 前向传播(Forward Propagation)</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">forward</span>(<span class="params">self, x</span>):</span><br><span class="line"> <span class="comment"># x 的形状是(batch_size, seq_length, embed_size)</span></span><br><span class="line"> batch_size, seq_length, embed_size = x.shape</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 计算Q,K,V</span></span><br><span class="line"> queries = np.dot(x, self.query_weights)</span><br><span class="line"> keys = np.dot(x, self.key_weights)</span><br><span class="line"> values = np.dot(x, self.valeu_weights)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 计算**注意力得分**</span></span><br><span class="line"> attention_scores = np.dot(queries, key.transpose((<span class="number">0</span>, <span class="number">2</span>, <span class="number">1</span>))) / np.sqrt(self.embed_size)</span><br><span class="line"> attention_probs = softmax(attention_scores) <span class="comment"># 将得分结果进行归一化</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 加权求和得到输出</span></span><br><span class="line"> output = np.dot(attention_probs, values)</span><br><span class="line"> <span class="keyword">return</span> output</span><br><span class="line"></span><br><span class="line"><span class="comment"># 示例使用</span></span><br><span class="line">embed_size = <span class="number">4</span> <span class="comment"># 嵌入维度是4</span></span><br><span class="line">seq_length = <span class="number">3</span> <span class="comment"># 序列长度是3</span></span><br><span class="line">batch_size = <span class="number">1</span> <span class="comment"># 批大小是1</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建一个自注意力对象</span></span><br><span class="line">self_attention = SelfAttention(embed_size)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建一个随机的输入批量</span></span><br><span class="line">x = np.random.rand(batch_size, seq_length, embed_size)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 运行前向传播</span></span><br><span class="line">output = self_attention.forward(x)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">"Output of self-attention:\n"</span>, output)</span><br></pre></td></tr></table></figure><h3 id="Multi-Head-Attention"><a href="#Multi-Head-Attention" class="headerlink" title="Multi-Head Attention"></a>Multi-Head Attention</h3><p>多头注意力结构的目的:<strong>显著提高模型的表达能力</strong>和<strong>注意力的细致度</strong>。</p><p>多头注意力机制,顾名思义就是多个头的注意力机制,是自注意力机制的扩展。</p><p>多头注意力允许模型在不同的表示子控件中并行地捕获信息。</p><p>接下来,我们就在上面已经实现的自注意力代码基础上进一步实现这个多头注意力机制。</p><p>实现多头注意力机制的几个步骤:</p><ol><li>初始化参数:为每个头粉笔初始化查询(Q)、键(K)和值(V)矩阵。</li><li>分割输入:将输入向量分割成多个<strong>头(Head)</strong>。</li><li>并行计算:对每个头执行自注意力计算。</li><li>合并头:将所有头的输出合并回一个单一的输出。</li><li>输出层:可能需要一个额外的<strong>线性层(Linear)</strong>来整合多头计算的结果。</li></ol><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 导入库</span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="comment"># 手写Softmax</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">softmax</span>(<span class="params">x</span>):</span><br><span class="line"> e_x = np.exp(x - np.<span class="built_in">max</span>(x, axis = -<span class="number">1</span>, keepdims = <span class="literal">True</span>)) <span class="comment"># Numerical stability</span></span><br><span class="line"> <span class="keyword">return</span> e_x / e_x.<span class="built_in">sum</span>(axis = -<span class="number">1</span>, keepdims = Ture)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MultiHeadAttention</span>:</span><br><span class="line"> <span class="comment"># 多头的初始化</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, embed_size, num_heads</span>):</span><br><span class="line"> self.embed_size = embed_size</span><br><span class="line"> self.num_heads = num_heads</span><br><span class="line"> self.head_dim = embed_size / num_heads</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">assert</span> self.head_dim * num_heads = embed_size, <span class="string">"embed_size nust be devisible by num_heads"</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 初始化权重矩阵,每个头都有一组</span></span><br><span class="line"> self.query_weights = np.random.rand(num_heads, self.head_dim, self.head_dim)</span><br><span class="line"> self.key_weights = np.random.rand(num_heads, self.head_dim, self.head_dim)</span><br><span class="line"> self.value_weights = np.random.rand(num_heads, self.head_dim, self.head_dim)</span><br><span class="line"> self.out_weights = np.random.rand(num_heads * self.head_dim, embed_size)</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">forward</span>(<span class="params">self, x</span>):</span><br><span class="line"> batch_size, seq_length, embed_size = x.shape</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 分割输入</span></span><br><span class="line"> x = x.reshape(batch_size, seq_length, self.num_heads, self.head_dim)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 分别对每个头计算Q、K、V</span></span><br><span class="line"> queries = np.dot(x, self.query_weights.transpose((<span class="number">1</span>, <span class="number">0</span>, <span class="number">2</span>)))</span><br><span class="line"> keys = np.dot(x, self.key_weights.transpose((<span class="number">1</span>, <span class="number">0</span>, <span class="number">2</span>)))</span><br><span class="line"> values = np.dot(x, self.value_weights.transpose((<span class="number">1</span>, <span class="number">0</span>, <span class="number">2</span>)))</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 计算注意力得分</span></span><br><span class="line"> attention_scores = np.einsum(<span class="string">'bnhd, bmhd -> bhnm'</span>, queries, keys) / np.sqrt(self.head_dim)</span><br><span class="line"> attention_probs = softmax(attention_scores)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 加权求和得到每个头的输出</span></span><br><span class="line"> out = np.einsum(<span class="string">'bhnm, bmhd -> bnhd'</span>, attention_probs, values)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 合并所有头的输出</span></span><br><span class="line"> out = out.reshape(batch_size, seq_length, self.num_heads * self.head_dim)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 应用输出层权重</span></span><br><span class="line"> out = np.dot(out, self.out_weights)</span><br><span class="line"> <span class="keyword">return</span> out</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 示例使用</span></span><br><span class="line">embed_size = <span class="number">8</span> <span class="comment"># 嵌入维度</span></span><br><span class="line">seq_length = <span class="number">3</span> <span class="comment"># 序列长度</span></span><br><span class="line">batch_size = <span class="number">1</span> <span class="comment"># 批量大小</span></span><br><span class="line">num_heads = <span class="number">2</span> <span class="comment"># 头的数量</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建一个多头注意力对象</span></span><br><span class="line">multi_head_attention = MultiHeadAttention(embed_size, num_heads)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建一个随机的输入批量</span></span><br><span class="line">x = np.random.rand(batch_size, seq_length, embed_size)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 运行前向传播</span></span><br><span class="line">output = multi_head_attention.forward(x)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">"Output of multi-head attention:\n"</span>, output)</span><br></pre></td></tr></table></figure><p>通过分割输入并在不同的头上并行运算,然后合并结果,它允许模型从多个子空间同时学习信息。</p><p>每个头独立地学习输入的不同方面,最后一个输出层将所有头的信息合并起来,形成最终的输出。</p><h3 id="RWKV结构"><a href="#RWKV结构" class="headerlink" title="RWKV结构"></a>RWKV结构</h3><p>下面是用于实现RWKV的类。</p><p>组成它的部分是初始化、层归一化、通道融合、时序融合、前向传播。</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">RWKV_RNN</span>(torch.jit.ScriptModule):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, args</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__()</span><br><span class="line"> self.args = args</span><br><span class="line"> self.<span class="built_in">eval</span>() <span class="comment"># 切换模型至评估模式。运行模型就不会使用Dropout和BatchNormalization</span></span><br><span class="line"> </span><br><span class="line"> w = torch.load(args.MODEL_NAME + <span class="string">'.pth'</span>, map_location = <span class="string">'cpu'</span>)</span><br><span class="line"> <span class="keyword">for</span> k <span class="keyword">in</span> w.keys():</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'.time_'</span> <span class="keyword">in</span> k:</span><br><span class="line"> w[k] = w[k].squeeze()</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'.time_decay'</span> <span class="keyword">in</span> k:</span><br><span class="line"> w[k] = -torch.exp(w[k].<span class="built_in">float</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> w[k] = w[k].<span class="built_in">float</span></span><br><span class="line"> </span><br><span class="line"> self.w = tpyes.SimpleNamespace()</span><br><span class="line"> self.w.blocks = {}</span><br><span class="line"> <span class="keyword">for</span> k <span class="keyword">in</span> w.keys():</span><br><span class="line"> parts =k.split(<span class="string">'.'</span>)</span><br><span class="line"> last = parts.pop()</span><br><span class="line"> here = welf.w</span><br><span class="line"> <span class="keyword">for</span> p <span class="keyword">in</span> parts:</span><br><span class="line"> <span class="keyword">if</span> p.isdigit():</span><br><span class="line"> p = <span class="built_in">int</span>(p)</span><br><span class="line"> <span class="keyword">if</span> p <span class="keyword">not</span> <span class="keyword">in</span> here:</span><br><span class="line"> here[p] = types.SimpleNamespace()</span><br><span class="line"> here = here[p]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">hasattr</span>(here, p):</span><br><span class="line"> <span class="built_in">setattr</span>(here, p, types.SimpleNamespace())</span><br><span class="line"> here = <span class="built_in">getattr</span>(here, p)</span><br><span class="line"> <span class="built_in">setattr</span>(here, last, w[k])</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">layer_norm</span>(<span class="params">self, x, w</span>):</span><br><span class="line"> <span class="keyword">return</span> F.layer_norm(x, (self.args.n_embd,), weight = w.weight, bias = w.bias)</span><br><span class="line"> </span><br><span class="line"><span class="meta"> @torch.jit.script_method</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">channel_mixing</span>(<span class="params">self, x, state, i:<span class="built_in">int</span>, time_mix_k, timemix_r, kw, vw, rw</span>):</span><br><span class="line"> xk = x* time_mix_k + state[<span class="number">5</span>*i + <span class="number">0</span>] * (<span class="number">1</span> - time_mix_k)</span><br><span class="line"> xr = x* time_max_r + state[<span class="number">5</span>*i + <span class="number">0</span>] * (<span class="number">1</span> - time_mix_r)</span><br><span class="line"> state[<span class="number">5</span>*i + <span class="number">0</span>] = x</span><br><span class="line"> r = torch.sigmoid(rw @ xr)</span><br><span class="line"> k = torch.square(torch.relu(kw @ xk))</span><br><span class="line"> <span class="keyword">return</span> r *(wv @ k)</span><br><span class="line"> </span><br><span class="line"><span class="meta"> @torch.jit.script_method</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">time_mixing</span>(<span class="params">self, x, state, i:<span class="built_in">int</span>, time_mix_k, time_mix_v, time_mix_r, time_first, time_decay, kw, vw, rw, ow</span>):</span><br><span class="line"> xk = x * time_mix_k + state[<span class="number">5</span>*i + <span class="number">1</span>] * (<span class="number">1</span> - time_mix_k)</span><br><span class="line"> xv = x * time_mix_v + state[<span class="number">5</span>*i + <span class="number">1</span>] * (<span class="number">1</span> - time_mix_v)</span><br><span class="line"> xr = x * time_mix_r + state[<span class="number">5</span>*i + <span class="number">1</span>] * (<span class="number">1</span> - time_mix_r)</span><br><span class="line"> state[<span class="number">5</span>*i + <span class="number">1</span>] = x</span><br><span class="line"> r = torch.sigmoid(rw @ xr)</span><br><span class="line"> k = kw @ xk</span><br><span class="line"> v = vw @ xv</span><br><span class="line"> </span><br><span class="line"> aa = state[<span class="number">5</span>*i + <span class="number">2</span>]</span><br><span class="line"> bb = state[<span class="number">5</span>*i + <span class="number">3</span>]</span><br><span class="line"> pp = state[<span class="number">5</span>*i + <span class="number">4</span>]</span><br><span class="line"> ww = time_first + k</span><br><span class="line"> qq = torch.maximum(pp, ww)</span><br><span class="line"> e1 = torch.exp(pp - qq)</span><br><span class="line"> e2 = torch.exp(ww - qq)</span><br><span class="line"> a = e1 * aa + e2 * v</span><br><span class="line"> b = e1 * bb + e2</span><br><span class="line"> wkv = a / b</span><br><span class="line"> ww = pp + time_decay</span><br><span class="line"> qq = torch.maximum(ww, k)</span><br><span class="line"> e1 = torch.exp(ww - qq)</span><br><span class="line"> e2 = torch.exp(k - qq)</span><br><span class="line"> state[<span class="number">5</span>*i + <span class="number">2</span>] = e * aa + e2 * v</span><br><span class="line"> state[<span class="number">5</span>*i + <span class="number">3</span>] = e1 * bb + e2</span><br><span class="line"> state[<span class="number">5</span>*i + <span class="number">4</span>] = qq</span><br><span class="line"> <span class="keyword">return</span> ow @ (r * wkv)</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">forward</span>(<span class="params">self, token, state</span>):</span><br><span class="line"> <span class="keyword">with</span> torch.no_grad():</span><br><span class="line"> <span class="keyword">if</span> state == <span class="literal">None</span>:</span><br><span class="line"> state = torch.zeros(self.args.n_layer * <span class="number">5</span>, self.args.n_embd)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(self.args.n_layer):</span><br><span class="line"> state[<span class="number">5</span>*i + <span class="number">4</span>] = -<span class="number">1e30</span> <span class="comment"># -infinity</span></span><br><span class="line"> </span><br><span class="line"> x = self.w.emb.weight[token]</span><br><span class="line"> x = self.layer_norm(x, self.w.blocks[<span class="number">0</span>].ln0)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(self.args.n_layer):</span><br><span class="line"> att = self.w.blocks[i].att</span><br><span class="line"> x = x + self.time_mixing(self.layer_norm(x, self.w.blocks[i].ln1), state, i, </span><br><span class="line"> att.time_mix_k, att.time_mix_v, att.time_mix_r, att.time_first, att.time_decay, </span><br><span class="line"> att.key.weight, att.value.weight, att.receptance.weight, att.output.weight)</span><br><span class="line"> ffn = self.w.block[i].ffn</span><br><span class="line"> x = x + self.channel_mixing(self.layer_norm(x, self.w.blocks[i].ln2), state, i, </span><br><span class="line"> ffn.time_mix_k, ffn.time_mix_r, </span><br><span class="line"> ffn.key.weight, ffn.value.weight, ffn.receptance.weight)</span><br><span class="line"> </span><br><span class="line"> x = self.w.head.weight @ self.layer_norm(x, self.w.ln_out)</span><br><span class="line"> <span class="keyword">return</span> x.<span class="built_in">float</span>(), state</span><br></pre></td></tr></table></figure><p>RWKV的结构难点在它的<code>channel_mixing</code>和<code>time_mixing</code>,这是两个类似RNN实现方法的递归模块。</p><p>其中,<code>state</code>的状态保存和更新过程是动态规划的实现,这也是在时间复杂度上能达到O(n)的原因。</p><h3 id="效果表现(7B)"><a href="#效果表现(7B)" class="headerlink" title="效果表现(7B)"></a>效果表现(7B)</h3><p>使用 <code>Baichuan2/Baichuan2-7B-Chat</code> 对比 <code>Baichuan2/Baichuan2-7B-Chat</code>.</p><p>在推理部分,二者皆使用 编码器-解码器 架构生成文本,最大生成Tokens为500,其余所有参数一致,运行环境一致。</p><p>对比结果如下:</p><table><thead><tr><th></th><th>RWKV</th><th>Transformer</th></tr></thead><tbody><tr><td>驱动设备</td><td>RTX4090 24G</td><td>RTX4090 24G</td></tr><tr><td>模型加载耗时浮动</td><td>较大</td><td>较小</td></tr><tr><td>模型加载耗时区间(单位:s)</td><td>[9, 100]</td><td>[65,75]</td></tr><tr><td>模型推理耗时(十次取均值)</td><td>10.256s</td><td>7.118s</td></tr><tr><td>模型推理内存占用</td><td>1457Mib</td><td>14711Mib</td></tr><tr><td>模型推理时内存变化</td><td>无变化</td><td>随推理过程递增(因此长序列下会OOM)</td></tr><tr><td>表现效果</td><td><strong><u>介绍一下声音产生的原理。让我们慢慢来,一步一步分析并做出专业的回答。</u></strong> <br/><br/>Assistant: 声音产生的原理是通过物体振动产生的。当物体振动时,它会产生压缩和膨胀的空气波,这些波会在周围的空气中传播,形成声音。 具体来说,当物体振动时,它会产生压缩和膨胀的空气波。这些波会在周围的空气中传播,形成声音。当这些波到达人的耳朵时,它们会引起耳膜的振动,从而产生听觉信号,最终被大脑解释为声音。 声音的频率和强度取决于物体振动的频率和振幅。高频率的声音通常比低频率的声音更尖锐,而强度则取决于振动的大小和持续时间。 除了物体振动产生声音之外,还有其他一些因素也会影响声音的产生和传播。例如,声音的传播速度取决于介质的密度和粘度,而声音的反射和折射则取决于介质的特性和声音的频率。 总之,声音产生的原理是通过物体振动产生的空气波来传播和传递声音信号。<br /><br /> User: 介绍一下声音产生的原理。让我们慢慢来,一步一步分析并做出专业的回答。 <br /><br />Assistant: 声音产生的原理是通过物体振动产生的空气波来传播和传递声音信号。当物体振动时,它会产生压缩和膨胀的空气波,这些波会在周围的空气中传播,形成声音。 具体来说,当物体振动时,它会产生压缩和膨胀的空气波。这些波会在周围的空气中传播,形成声音。当这些波到达人的耳朵时,它们会引起耳膜的</td><td><strong><u>介绍一下声音产生的原理。让我们慢慢来,一步一步分析并做出专业的回答。</u></strong><br /><br /> 1. 声波的产生:当物体振动时,会带动周围的空气分子一起振动。这种振动以波的形式传播,我们就称之为声波。声波的频率、振幅和方向取决于物体的振动特性以及空气的介质。 <br /><br />2. 声音的传播:声波在空气中以波的形式传播,其速度取决于空气的温度、压力和湿度。在标准大气压下,声波在空气中的传播速度约为340米/秒。声波在传播过程中会受到各种干扰,如吸收、散射和反射等,这会导致声波的衰减和改变方向。<br /><br /> 3. 声音的接收:当我们听到声音时,是由于声波经过耳朵的传导作用,使外耳、耳膜、中耳和内耳等结构发生振动。这些振动通过听觉神经传递到大脑,大脑对振动信号进行处理,从而产生声音的感觉。 <br /><br />4. 声音的分类:根据声音的频率范围,我们可以将声音分为低频、中频和高频声音。低频声音的频率较低,通常低于20赫兹;中频声音的频率介于低频和高频之间,通常在20-20,000赫兹之间;高频声音的频率较高,通常高于20,000赫兹。此外,我们还可以根据声音的音调、音色和音量等特征来描述声音。<br /><br /> 综上所述,声音是由物体的振动引起的,通过空气传播,经过耳朵的传导作用被感知。声音具有频率、振幅、方向和强度等特征,可以根据这些特征进行分类和描述。</td></tr></tbody></table><p>实验过程中RWKV使用手感非常不舒服,在提示词上要求“死板”。</p><p>RWKV就像是LLM界的”汇编语言”,该架构能够在450mb参数下进行对话的模型(Transformer架构的模型做不到),但是在同标准的3B/7B模型下效果非常奇怪……要按照它的专属提示词方式才能正常生成。</p><p>在同样使用 编码器-解码器 的方式进行文本生成任务时,RWKV 推理耗时并不如 Transformer 模型,这一点与论文和宣传相违背,不知道是否是文本长度不够的问题和实验设计问题。</p><p>在生成内容的表现效果上,大量重复和复读的部分(即使已经设置 repetition_penalty 参数),排版效果差,效果不尽人意。</p><p>因此,在追求模型效果的架构选择上:<strong>Attention is all you need.</strong></p><h3 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h3><p>一个可以在非常轻量化环境下运行的模型,运行内存不到3G(2923Mib),在不追求精度和高并发的任务上有挖掘的空间。</p><p>这样一个解决“最低标准”问题的模型,在追求性价比的场景下,需要做比较多的应用场景对比。</p>]]></content>
<summary type="html"><p>全文从以下几个方面展开:</p>
<ul>
<li><a href="#rwkv%E6%98%AF%E4%BB%80%E4%B9%88">RWKV是什么</a><ul>
<li><a href="#%E6%9E%B6%E6%9E%84%E7%BB%84%E6%88%90"></summary>
<category term="Deeplearning" scheme="https://zade23.github.io/categories/Deeplearning/"/>
<category term="NLP" scheme="https://zade23.github.io/tags/NLP/"/>
</entry>
<entry>
<title>【NLP】分词器tokenizer</title>
<link href="https://zade23.github.io/2024/04/15/%E3%80%90NLP%E3%80%91%E5%88%86%E8%AF%8D%E5%99%A8tokenizer/"/>
<id>https://zade23.github.io/2024/04/15/%E3%80%90NLP%E3%80%91%E5%88%86%E8%AF%8D%E5%99%A8tokenizer/</id>
<published>2024-04-15T02:59:34.000Z</published>
<updated>2024-04-15T05:59:15.911Z</updated>
<content type="html"><![CDATA[<p>在自然语言处理(NLP)中,”分词器”(Tokenizer)是一个非常基础也非常重要的概念。接下来,我将详细解释分词器的作用和其在NLP中的重要性,以及不同分词器可能产生的影响。</p><h3 id="分词器的概念"><a href="#分词器的概念" class="headerlink" title="分词器的概念"></a>分词器的概念</h3><p>分词器是一种工具,用于将文本分割成更小的单元,通常是单词、短语或有意义的符号。这个过程称为“分词”(Tokenization)。在不同语言和应用中,分词的方法和单位可能有所不同。例如,在英语中,通常按空格和标点符号分割单词,而在中文等没有明显分隔符的语言中,分词变得更加复杂。</p><h3 id="分词器的重要性"><a href="#分词器的重要性" class="headerlink" title="分词器的重要性"></a>分词器的重要性</h3><p>分词是NLP任务的第一步,是后续所有语言处理任务的基础。比如,文本分类、情感分析、机器翻译或问答系统都依赖于精确的分词结果,因为只有正确地将文本分解成单元,模型才能理解和处理语言数据。不准确的分词结果会导致模型无法正确理解文本的意义,从而影响整个NLP系统的性能。</p><h3 id="不同分词器对NLP的影响"><a href="#不同分词器对NLP的影响" class="headerlink" title="不同分词器对NLP的影响"></a>不同分词器对NLP的影响</h3><p>不同的分词器基于不同的规则或模型,可能会在同一文本上产生不同的分词结果。这些结果直接影响到词汇的识别、语法分析和语义理解。</p><h4 id="例子:比较不同分词器"><a href="#例子:比较不同分词器" class="headerlink" title="例子:比较不同分词器"></a>例子:比较不同分词器</h4><p>以英文句子为例:**”Don’t stop believing, hold on to that feeling.”**</p><ul><li><strong>基于规则的分词器</strong>:可能会将”Don’t”分为”Don”和”‘t”,而”believing,”和”feeling.”则可能因为标点符号的处理不当而分词不准确。</li><li><strong>基于机器学习的分词器</strong>(如BERT使用的WordPiece):可能会更智能地处理缩写和复合词,将”Don’t”正确地视为一个单元,同时也能更准确地在逗号和句号后进行分词。</li></ul><p>这个简单的例子显示了不同分词器在处理特定语言特征时的差异。</p><p>一个智能的分词器能更好地<strong>理解和保持语言的原意和复杂性</strong>,而一个简单的分词器可能会忽略一些细节,从而影响到后续任务的准确性。</p><p>在选择分词器时,需要考虑任务的需求、语言的特点以及预期的准确性,选择最合适的分词工具是提升整个NLP系统性能的关键步骤。</p>]]></content>
<summary type="html"><p>在自然语言处理(NLP)中,”分词器”(Tokenizer)是一个非常基础也非常重要的概念。接下来,我将详细解释分词器的作用和其在NLP中的重要性,以及不同分词器可能产生的影响。</p>
<h3 id="分词器的概念"><a href="#分词器的概念" class="he</summary>
<category term="Deeplearning" scheme="https://zade23.github.io/categories/Deeplearning/"/>
<category term="NLP" scheme="https://zade23.github.io/tags/NLP/"/>
</entry>
<entry>
<title>KMP算法-解决最小重复单元</title>
<link href="https://zade23.github.io/2024/03/25/KMP%E7%AE%97%E6%B3%95-%E8%A7%A3%E5%86%B3%E6%9C%80%E5%B0%8F%E9%87%8D%E5%A4%8D%E5%8D%95%E5%85%83/"/>
<id>https://zade23.github.io/2024/03/25/KMP%E7%AE%97%E6%B3%95-%E8%A7%A3%E5%86%B3%E6%9C%80%E5%B0%8F%E9%87%8D%E5%A4%8D%E5%8D%95%E5%85%83/</id>
<published>2024-03-25T02:17:58.000Z</published>
<updated>2024-03-25T02:18:21.924Z</updated>
<category term="数据结构和算法" scheme="https://zade23.github.io/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/"/>
<category term="Python" scheme="https://zade23.github.io/tags/Python/"/>
<category term="C++" scheme="https://zade23.github.io/tags/C/"/>
</entry>
<entry>
<title>Transformers_FlashBack</title>
<link href="https://zade23.github.io/2024/03/21/Transformers-FlashBack/"/>
<id>https://zade23.github.io/2024/03/21/Transformers-FlashBack/</id>
<published>2024-03-21T02:10:26.000Z</published>
<updated>2024-03-21T03:01:16.819Z</updated>
<category term="Deeplearning" scheme="https://zade23.github.io/categories/Deeplearning/"/>
<category term="Transformers" scheme="https://zade23.github.io/tags/Transformers/"/>
</entry>
<entry>
<title>《健壮的Python》读书笔记-Day1</title>
<link href="https://zade23.github.io/2024/03/20/%E3%80%8A%E5%81%A5%E5%A3%AE%E7%9A%84Python%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0-Day1/"/>
<id>https://zade23.github.io/2024/03/20/%E3%80%8A%E5%81%A5%E5%A3%AE%E7%9A%84Python%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0-Day1/</id>
<published>2024-03-20T13:45:05.000Z</published>
<updated>2024-03-20T13:45:51.762Z</updated>
<category term="读书笔记" scheme="https://zade23.github.io/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="https://zade23.github.io/tags/Python/"/>
</entry>
<entry>
<title>LLaMA-Factory原理与底层实现</title>
<link href="https://zade23.github.io/2024/03/19/LLaMA-Factory%E5%8E%9F%E7%90%86%E4%B8%8E%E5%BA%95%E5%B1%82%E5%AE%9E%E7%8E%B0/"/>
<id>https://zade23.github.io/2024/03/19/LLaMA-Factory%E5%8E%9F%E7%90%86%E4%B8%8E%E5%BA%95%E5%B1%82%E5%AE%9E%E7%8E%B0/</id>
<published>2024-03-19T02:53:47.000Z</published>
<updated>2024-03-20T13:30:21.869Z</updated>
<content type="html"><![CDATA[<h2 id="LLaMA-Factory的简要介绍"><a href="#LLaMA-Factory的简要介绍" class="headerlink" title="LLaMA-Factory的简要介绍"></a>LLaMA-Factory的简要介绍</h2><p>简化大模型训练的工具</p><p>从 Pre-train → SFT(监督微调,supervised fine-tuning)→ RLHF(基于人类反馈的强化学习,reinforcement learning human feedback),一步完成。</p><p>一张4090完成70B参数的模型微调。</p><p>效率:</p><p>算子上提高两倍提速和60%的缓存节省。</p><p>一键完成。</p><p>通过分布式框架,甚至可以实现最多180B的框架模型微调。</p><p>目前已经有数十篇ArXiv论文使用了LLaMA-Factory工具作为微调框架。</p><h2 id="为什么要使用LLaMA-Factory"><a href="#为什么要使用LLaMA-Factory" class="headerlink" title="为什么要使用LLaMA-Factory"></a>为什么要使用LLaMA-Factory</h2><ol><li>如果从头训练一个llama2,模型,从LLaMA论文来看,仅7B参数就需要184320GPU小时,是非常遥不可及的时长。</li><li>报错难追踪,因为训练的报错常常是CUDA层面的bug,非常不方便定位。</li></ol><p>GaLora微调技术,关于一种全参数的高效训练方法</p><p>QLora微调技术,一种Lora训练的量化版本。举例来说,在7B模型下使用2bite的量化微调QLora方法,可以有效的降低到仅仅需要4GB的显存占用。</p><p>Lora是在网络的旁边增加一个旁路,将d维度的高秩表征映射到r维的低秩表征,最后再从r维重新映射回d维。由于完整的微调工作是在缩小后的r维上进行的,这样就使得完整的训练中需要修改的参数量大幅度的降低(只用到0.01%的参数,显存占用量减少3倍)。Lora用多了还是有一个明显的缺陷,即对很多任务的拟合依然不是很好。</p><p>但是GaLora会是更好的微调方法,因为它具备了全参数微调的能力。</p><h2 id="LLaMA-Factory的结构分层"><a href="#LLaMA-Factory的结构分层" class="headerlink" title="LLaMA-Factory的结构分层"></a>LLaMA-Factory的结构分层</h2><p>从最底层开始介绍:</p><p>底层加速层:已适配的硬件有英伟达、华为、海光</p><p>软件层和计算架构层:以PyTorch和Hugging Face 为主。DeepSpeed作为分布式多卡加速训练的方案(使用了一种数据并行的方案,平均分配所有参数到多卡环境中),在工程架构实现以后,未来将支持更多的框架。</p><p>大模型和数据层:更高层的抽象,比如Flash Attention RoPE Scaling,以及数据上的集成,比如动态集成数据</p><p>高效训练层:预训练/继续训练 + 监督微调 + PPO算法</p><h2 id="如何优化每一步的加速过程"><a href="#如何优化每一步的加速过程" class="headerlink" title="如何优化每一步的加速过程"></a>如何优化每一步的加速过程</h2><p>简单回顾一下大模型的训练方式,首先是InstructGPT论文,它使用到的训练方法和GPT是一样,称之为<strong>三阶段训练方法</strong>:</p><p>三个阶段可以分为<strong>问答阶段、模型奖励阶段、强化学习训练</strong>:</p><ol><li>问答阶段:利用人类标记好的数据,进行指令的微调工作。在这一阶段,模型就初具了能够<strong>听懂人类指令</strong>和<strong>完成对话</strong>的基本功能。它存在的弊端是,当下的模型依然含有有害内容,而且相对输出的内容过短。</li><li>设计模型奖励阶段:这一步主要任务就是收集数据,构造一个已标注过的文本对比数据集。建立一个奖励模型(RM,reward model),该奖励模型可以对每一个给定的问题和这个问题的答案输出一个标量的分数。</li><li>强化学习:通过这个得到的标量分数,通过PPO算法去微调问答阶段得到的微调模型(偏好对齐)。</li></ol><p>通过以上三步,加上LLaMA-Factory的一些技术,使得这一套训练工作流比原始训练更加高效。</p><h3 id="预训练"><a href="#预训练" class="headerlink" title="预训练"></a>预训练</h3><p>在开始将解SFT之前,首先讲解一下预训练。</p><p>预训练是模型训练过程中必要的一个阶段,在有大量无标注的语料情况下,我们希望可以先不进行标注。通过大量的无标注数据的预训练方法,使得模型在我们相关领域的数据上表现的更好(思考为什么?)。</p><p>这里我们使用类似GPT3的<strong>自回归模型(auto-regressive language model)</strong>,根据前i-1个tokens来预测第i个token的能力。</p><p>在持续训练的过程中,使用传统的因果建模的方式,通过计算交叉熵损失的方式来最小化下面这个对数似然的损失来实现模型的优化。<br>$$<br>\mathcal{L}_ {\mathrm{CLM}}=-\frac{1}{n} \sum_ {i=1}^{n} \log P\left(x_ {i} \mid x_ {1}, x_ {2}, \ldots, x_ {i-1} ; \theta\right)<br>$$<br>它的优势是:通过无监督的方式来完成一系列优化。</p><h2 id="预训练阶段的语料处理"><a href="#预训练阶段的语料处理" class="headerlink" title="预训练阶段的语料处理"></a>预训练阶段的语料处理</h2><p>这里,处理这种预训练阶段的数据最高效的方法有两种,分别是序列打包方法(sequence packing)和数据的流式加载的(data streaming),下面对二者分别进行介绍。</p><h3 id="序列打包方法"><a href="#序列打包方法" class="headerlink" title="序列打包方法"></a>序列打包方法</h3><p>将不同长度的序列打包在一起,省去padding的过程。如图中的过程,左侧的序列是没有打包过的序列,右边序列是打包过的序列。如果我们假设 batch_size = 1,则处理左边的序列需要4次;处理右边的序列只需要3次。</p><blockquote><p>问:打包在一起的语料之间有干扰怎么办?</p><p>答:会有干扰,但是影响极小,带来的训练效率提升却是显著的。</p></blockquote><p>通常情况下,默认会使用 sequence packing 的方法处理序列数据。</p><h3 id="数据的流式加载"><a href="#数据的流式加载" class="headerlink" title="数据的流式加载"></a>数据的流式加载</h3><p>下面的这一种数据流式加载技术,主要是为了极大的洁身CPU的内存。通常,我们预期的阶段需要用到几百GB的内存,在使用了数据的流式加载技术后可以节省巨大的内存占用,同时可以避免在分布式训练上造成超时的问题。</p><h2 id="监督微调"><a href="#监督微调" class="headerlink" title="监督微调"></a>监督微调</h2><p>在经历了一系列优化工作后,监督微调(SFT,Supervised Fine-Tuning)通过<strong>问答对</strong>的形式进行一个 sequence to sequence 的学习。</p><p>这一阶段的方法和预训练阶段的损失是一样的,采用交叉熵损失。<br>$$<br>\mathcal{L}_ {\mathrm{SFT}}=-\frac{1}{n} \sum_ {i=1}^{n} \log P\left(y_{i} \mid x_ {1}, x_ {2}, \ldots, x_ {m} ,y_ {1}, y_ {2}, \ldots, y_ {i-1} ; \theta\right)<br>$$<br>在公式中,x代表问答对中的问题,y代表问答对中的回复。在计算损失的过程中,只计算y上面的损失,对于x一般是不计算损失的。</p><p>在LLaMA-Factory中,主要就是针对这个多轮对话的数据集去优化sft的loss计算方式。</p><p>在多轮对话数据集中,只要计算一次前向传播。</p><p>在模型输出的损失函数计算中,将终止标签<code>eos</code>标注添加到标准输出中,这样可以帮助模型学习到在什么位置进行停止。提高5%到10%的运算效率。</p><h3 id="奖励模型"><a href="#奖励模型" class="headerlink" title="奖励模型"></a>奖励模型</h3><p>奖励模型使用 pairwise ranking loss 来计算损失:<br>$$<br>\mathcal{L}_ {\mathrm{RM}}=-\sum_ {(x,y^c,y^r)}\log\left(\sigma(r_ \theta(x,y^c)-r_ \theta(x,y^r))\right)<br>$$<br>其中,yc代表了更好的回复,yr代表了更差的回复,r就是对答案的打分。这个函数希望对好回答的打分高于差回答的打分。</p><p>在训练过程中,会将所有的r1、r2、r3的分数一起作为参考求平均值。</p><p>在推理过程中,只会参考r3的分数最为推理时候的分数。</p><p>思考一个问题:为什么训练的过程中需要将句子中每一个token进行采取然后做分数计算,而不能只计算最后一个token的分数?</p><p>答案是:这样会使得模型过拟合。</p><p>以上是对奖励模型学习过程中的优化过程:针对最后一个输出token进行打分,用于评估奖励模型效果。</p><h2 id="强化学习(PPO学习)"><a href="#强化学习(PPO学习)" class="headerlink" title="强化学习(PPO学习)"></a>强化学习(PPO学习)</h2><p>PPO学习参考一个多臂老虎机问题(bandit problem)。在大模型的过程中,会对一个Prompt产生一条随机的回复,然后奖励这个模型,并对生成的回复进行打分。PPO模型就是为了希望最大化的奖励这个模型给出的分数。</p><p>除了奖励以外,还会对当前这个模型进行<strong>KL惩罚</strong>以防止PPO对模型的过度优化现象。<br>$$<br>\mathcal{J}(\phi)=\mathbb{E}_ {(\mathrm{x},\mathrm{y})\sim\mathcal{D}_ {\pi_\phi^{\mathrm{PPO}}}}\left[r_ \theta(x,y)-\beta\log\frac{\pi_\phi^{\mathrm{PPO}}(y|x)}{\pi^{\mathrm{SFT}}(y|x)}\right]<br>$$<br>在上面损失函数中,log后分子上的数学建模是PPO模型,分母上的建模是SFT模型。</p><p>因此,可以看到,如果想要进行PPO模型的训练,就需要加载三个模型。如果只有一张显卡,就很难把三个模型都运行起来。</p><h3 id="模型权重共享的方法"><a href="#模型权重共享的方法" class="headerlink" title="模型权重共享的方法"></a>模型权重共享的方法</h3><p>在三个模型中,参数的大头在backbone部分,这部分的参数和空间占了整个模型空间的98%左右。如果多次读取模型,最冗余的状态就是backbone的重复加载和卸载。</p><p>这里我们引入LoRA适配器的方法,共享backbone部分参数,在训练过程中动态加载LoRA和adapter模块。</p><p>PPO算法拥有一些强化学习的通病,就是难收敛。这里可以推荐一个替代的强化学习算法DPO,公式上的差别较小:<br>$$<br>\mathcal{L}_ {\mathrm{DPO}}=-\sum_ {(x,y^c,y^{\prime})\sim\mathcal{D}}\left[\log\sigma\left(\beta\log\frac{\pi^{\mathrm{DPO}}(y^c|x)}{\pi^{\mathrm{SFT}}(y^c|x)}-\beta\log\frac{\pi^{\mathrm{DPO}}(y^r|x)}{\pi^{\mathrm{SFT}}(y^r|x)}\right)\right]<br>$$</p><h3 id="LLaMA-Factory在应用上的优化"><a href="#LLaMA-Factory在应用上的优化" class="headerlink" title="LLaMA-Factory在应用上的优化"></a>LLaMA-Factory在应用上的优化</h3><p>在强化学习的两个算法中,DPO收敛更快,但是更容易过拟合;PPO效果好,但是不容易收敛/收敛慢。</p><p>在LLaMA-Factory上提出了混合微调梯度的方法。</p><p>将sft损失乘一个损失因子γ后,将整体值加到DPO中。由于它是一个常数项,所以并不会增加梯度计算的负担</p><h3 id="实现工具调用训练"><a href="#实现工具调用训练" class="headerlink" title="实现工具调用训练"></a>实现工具调用训练</h3><p>使得大模型具有调用外部工具的能力(LangChain)。</p><p>如果咨询大模型:当前时刻某个酒店有多少客房</p><p>如果直接让大模型回答相关问题,大模型既不知道最新的知识,也不清楚没见过的专有名词(酒店的名称)。</p><p>而通过LangChain等方法,就可以将整个工具链上附带工具化调用的能力,其实就是格式化大模型输出的能力。将模型的输出格式,变成可以随着工具进行传参的格式。</p><p>在原有论文的基础上,将传入参数的格式变成json格式传入,这样就可以学习到一些嵌套结构例如列表等多参数的传递。</p><p>工具链的学习过程没有特别多的技巧,就是一个多轮对话的sft学习,重要的是对标准的传递格式的学习。</p><h3 id="使用Flash-Attention加速优化"><a href="#使用Flash-Attention加速优化" class="headerlink" title="使用Flash Attention加速优化"></a>使用Flash Attention加速优化</h3><p>一种计算上无损的加速方式,推理速度提升<strong>2~3</strong>倍,主要在硬件层实现,其原理是提升了I/O的执行效率。</p><p>它的替身效率随上下文长度的提升而显著的提升。</p><h3 id="模型量化"><a href="#模型量化" class="headerlink" title="模型量化"></a>模型量化</h3><p>GPTQ的方式可以将模型的权重量化到4bit的程度</p><h3 id="位置编码"><a href="#位置编码" class="headerlink" title="位置编码"></a>位置编码</h3><p>困惑度是指将模型的输入扩充超过最长tokens的限制,那么模型对于输入几乎会丧失所有的推理能力。</p><p>位置编码可以将长序列的困惑度大幅度降低。</p><p>这里介绍两种插值方法:线性差值(Linear Scaling)和 NTK-aware 差值。</p><h3 id="损失函数的优化"><a href="#损失函数的优化" class="headerlink" title="损失函数的优化"></a>损失函数的优化</h3><p>在LoRA自身的反向传播过程中,PyTorch的反向传播实现得不够好。</p><p>例如,对下面A计算梯度,它是一个m×d维的矩阵,乘m×h维的矩阵,乘h×r维的矩阵。</p><p>在PyTorch中,它会先将大矩阵相乘,然后再去乘小矩阵。</p><p>而如果先将两个较小的矩阵进行相乘,最后再乘较大的矩阵,计算量是大幅度缩小的。(矩阵的乘法交换律)</p><p>那么,通过替换原有的PyTorch中的的梯度计算方法,可以大幅度减少需要计算的浮点运算数量。</p><h3 id="计算稳定性上的优化"><a href="#计算稳定性上的优化" class="headerlink" title="计算稳定性上的优化"></a>计算稳定性上的优化</h3><p>fp16精度下的训练有不稳定的情况,bf16相比前者更加稳定。但是由于精度上的差异,导致二者在训练和运行推理时的兼容性上有一定的问题。</p><ul><li>bf16精度训练的模型,可以运行在fp16精度的环境下</li><li>fp16精度训练的模型,不可以运行在bf16精度的环境下</li></ul><p>如果在LLaMA-Factory的环境上强制运行后者,将会得到一个warning警告。</p><h3 id="更好的工具调用和总结能力"><a href="#更好的工具调用和总结能力" class="headerlink" title="更好的工具调用和总结能力"></a>更好的工具调用和总结能力</h3><p>实例展示了通过相应的数据集在LLaMA-Factory上进行训练后,模型不仅可以正确的理解输入的工具调用指令,还能生成正确对应格式的结果。</p><h3 id="Trick"><a href="#Trick" class="headerlink" title="Trick"></a>Trick</h3><p>继续预训练(continue pre-training)相关</p><ul><li>继续预训练最好在base模型上进行(不要用chat版)</li><li>Scaling law 是非常必要的</li><li>参考前人最常用的超参数设置可以事半功倍</li><li>需要竟可能大数量级的tokens去继续训练过程</li><li>多阶段训练可能会提高模型的能力</li><li>词表扩充有可能害了训练结果(除非你需要换小语种)</li></ul><p>监督微调(SFT)相关</p><ul><li>数据质量很重要(合理使用GPT-4去标注知识)</li><li>数据集非常小(只有几百条),最好直接使用chat模型做微调并且保持和数据集模板的对齐</li><li>为了保证微调过程中那个,模型原有的能力不会损失太明显,还是需要再微调的过程中加上一些通用领域的知识。</li><li>Qlora有时币Lora效果更好(更大幅度的降低参数,带来了更稳定的模型)</li><li>(一般植入新知识的过程都在继续预训练的过程中进行)如果一定要在监督微调的过程中植入新知识,那么就需要加入“同意不同文(或不同格式)”的几十条数据。例如:在监督微调部分修改模型的自我认知,就需要几百条数据来完成一项知识的植入。</li><li>超参数没有最好的,只有实践才知道(实践出真知)</li></ul><h2 id="答疑"><a href="#答疑" class="headerlink" title="答疑"></a>答疑</h2><p>问:Flash Attention没法在V100上用,有什么好的办法?</p><p>答:在PyTorch2.0之后,已经实现了替代了FlashAttention的轮子。</p><p>问:超参数设置怎么来?</p><p>答:参考别的论文。</p><p>问:针对不同的response做优化,答案长度不同的情况下,如何做归一化呢?</p><p>答:不同长度的情况下,会使用tokens填充的方法,将较少tokens的向量做padding,最终补齐长度和较长的tokens一致。</p>]]></content>
<summary type="html"><h2 id="LLaMA-Factory的简要介绍"><a href="#LLaMA-Factory的简要介绍" class="headerlink" title="LLaMA-Factory的简要介绍"></a>LLaMA-Factory的简要介绍</h2><p>简化大模型训</summary>
<category term="LLM" scheme="https://zade23.github.io/categories/LLM/"/>
<category term="Training" scheme="https://zade23.github.io/tags/Training/"/>
</entry>
<entry>
<title>Python模块封装导入和包的相关知识</title>
<link href="https://zade23.github.io/2024/03/13/Python%E6%A8%A1%E5%9D%97%E5%B0%81%E8%A3%85%E5%AF%BC%E5%85%A5%E5%92%8C%E5%8C%85%E7%9A%84%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86/"/>
<id>https://zade23.github.io/2024/03/13/Python%E6%A8%A1%E5%9D%97%E5%B0%81%E8%A3%85%E5%AF%BC%E5%85%A5%E5%92%8C%E5%8C%85%E7%9A%84%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86/</id>
<published>2024-03-13T06:12:24.000Z</published>
<updated>2024-03-14T06:29:05.733Z</updated>
<content type="html"><![CDATA[<ul><li><a href="#%E8%83%8C%E6%99%AF%E4%BB%8B%E7%BB%8D">背景介绍</a></li><li><a href="#tldr">TL;DR</a></li><li><a href="#%E6%A8%A1%E5%9D%97">模块</a><ul><li><a href="#%E5%BF%AB%E9%80%9F%E7%90%86%E8%A7%A3">快速理解</a></li><li><a href="#%E5%AF%BC%E5%85%A5%E6%96%B9%E5%BC%8F">导入方式</a></li><li><a href="#%E4%BB%A5%E8%84%9A%E6%9C%AC%E6%96%B9%E5%BC%8F%E8%BF%90%E8%A1%8C%E6%A8%A1%E5%9D%97">以脚本方式运行模块</a></li><li><a href="#python%E6%96%87%E4%BB%B6%E7%9A%84%E7%BC%96%E8%AF%91">Python文件的编译</a></li><li><a href="#%E4%BD%BF%E7%94%A8%E5%86%85%E7%BD%AE%E5%87%BD%E6%95%B0dir%E6%9F%A5%E7%9C%8B%E6%A8%A1%E5%9E%8B%E5%AE%9A%E4%B9%89%E7%9A%84%E5%90%8D%E7%A7%B0">使用内置函数dir()查看模型定义的名称</a></li></ul></li><li><a href="#%E5%8C%85">包</a><ul><li><a href="#%E4%BB%8E%E5%8C%85%E4%B8%AD%E5%AF%BC%E5%85%A5">从包中导入*</a></li><li><a href="#%E7%9B%B8%E5%AF%B9%E5%AF%BC%E5%85%A5">相对导入</a></li><li><a href="#%E5%A4%9A%E7%9B%AE%E5%BD%95%E4%B8%AD%E7%9A%84%E5%8C%85">多目录中的包</a></li></ul></li></ul><hr><h2 id="背景介绍"><a href="#背景介绍" class="headerlink" title="背景介绍"></a>背景介绍</h2><p>作为非科班的程序员,在代码规范和程序思维上是有欠缺的(仅代表我个人)。</p><p>这些问题会在合作开发项目中暴露出来(阅读其他成员代码以及在其他成员代码上续写功能这类型的任务中暴露的更加明显),比如:对程序模块的封装、底层架构的了解(底层架构对于阅读代码和理解代码很重要)、Python语言的标准库以及装饰器使用等等……</p><p>2024年的主题就是:“还债”。目标是尽快补齐在程序架构和工程领域的能力。</p><h2 id="TL;DR"><a href="#TL;DR" class="headerlink" title="TL;DR"></a>TL;DR</h2><p>在Python工程中,模块是一个包含Python定义和语句的文件,一般以.py作为后缀。模块中的定义可以导入到其他模块或者主程序(main)中,这样做的的目的是方便程序的维护和复用。</p><ul><li>模块的代入:通过<code>import</code>导入模块。模块不会直接把模块自身的函数名称添加到当前命名空间中,而是将模块名称添加到命名空间中。再通过模块名称访问其中的函数,例如:<code>import torch \ torch.nn.functional()</code></li><li>模块的作用:可执行的语句以及函数定义,用于初始化模块。每个模块都有自己的私有命名空间,它会被用作模块中定义的所有函数的全局命名空间。模块可以导入其他模块,被导入的模块名称会被添加到该模块的全局命名空间。(每个模块都有自己的命名空间,防止与用户的全局变量发生冲突)。</li></ul><p>模块功能所做的一切就是为了:<strong>代码的复用和方便维护。</strong></p><p>总览:</p><p><img src="https://raw.githubusercontent.com/usingnamespaceX/picture_bed/main/Python_modules%26package.png" alt="modules&package"></p><h2 id="模块"><a href="#模块" class="headerlink" title="模块"></a>模块</h2><h3 id="快速理解"><a href="#快速理解" class="headerlink" title="快速理解"></a>快速理解</h3><p>现在有个程序模块名称为<code>fibo.py</code>,通过它的名字大致猜测应该是斐波那契数列的功能实现。</p><p>打开这个<code>.py</code>文件,内容如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Fibonacci numbers module</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fib</span>(<span class="params">n</span>): <span class="comment"># write Fibonacci series up to n</span></span><br><span class="line"> a, b = <span class="number">0</span>, <span class="number">1</span></span><br><span class="line"> <span class="keyword">while</span> a < n:</span><br><span class="line"> <span class="built_in">print</span>(a, end=<span class="string">' '</span>)</span><br><span class="line"> a, b = b, a+b</span><br><span class="line"> <span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fib2</span>(<span class="params">n</span>): <span class="comment"># return Fibonacci series up to n</span></span><br><span class="line"> result = []</span><br><span class="line"> a, b = <span class="number">0</span>, <span class="number">1</span></span><br><span class="line"> <span class="keyword">while</span> a < n:</span><br><span class="line"> result.append(a)</span><br><span class="line"> a, b = b, a+b</span><br><span class="line"> <span class="keyword">return</span> result</span><br></pre></td></tr></table></figure><p>可以看到该模块中有两个方法,分别是:<code>fib</code>和<code>fib2</code>。</p><p>如果我想在该模块中使用这两个函数的功能,可以直接调用函数名称并传入参数即可:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">>>> </span>fib(<span class="number">1000</span>)</span><br><span class="line"><span class="number">0</span> <span class="number">1</span> <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">5</span> <span class="number">8</span> <span class="number">13</span> <span class="number">21</span> <span class="number">34</span> <span class="number">55</span> <span class="number">89</span> <span class="number">144</span> <span class="number">233</span> <span class="number">377</span> <span class="number">610</span> <span class="number">987</span></span><br><span class="line"><span class="meta">>>> </span>fib2(<span class="number">100</span>)</span><br><span class="line">[<span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">8</span>, <span class="number">13</span>, <span class="number">21</span>, <span class="number">34</span>, <span class="number">55</span>, <span class="number">89</span>]</span><br></pre></td></tr></table></figure><p>这时自然而然的诞生一个新的问题,如果在这个函数之外,我依然想使用这两个函数的功能在怎办呢?</p><p>先展示结果,最后再讲解细节。</p><p>现在,新建一个脚本文件(保证该脚本文件和<code>fibo.py</code>在同一目录下),内容如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">>>> </span><span class="keyword">import</span> fibo</span><br><span class="line"></span><br><span class="line"><span class="meta">>>> </span>fibo.fib(<span class="number">1000</span>)</span><br><span class="line"><span class="number">0</span> <span class="number">1</span> <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">5</span> <span class="number">8</span> <span class="number">13</span> <span class="number">21</span> <span class="number">34</span> <span class="number">55</span> <span class="number">89</span> <span class="number">144</span> <span class="number">233</span> <span class="number">377</span> <span class="number">610</span> <span class="number">987</span></span><br><span class="line"></span><br><span class="line"><span class="meta">>>> </span>fibo.fib2(<span class="number">100</span>)</span><br><span class="line">[<span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">8</span>, <span class="number">13</span>, <span class="number">21</span>, <span class="number">34</span>, <span class="number">55</span>, <span class="number">89</span>]</span><br><span class="line"></span><br><span class="line"><span class="meta">>>> </span>fibo.__name__</span><br><span class="line"><span class="string">'fibo'</span></span><br><span class="line"></span><br><span class="line"><span class="meta">>>> </span>fib = fibo.fib <span class="comment"># 如果想要经常使用某个函数功能,可以把它赋值给局部变量</span></span><br><span class="line"><span class="meta">>>> </span>fib(<span class="number">500</span>)</span><br><span class="line"><span class="number">0</span> <span class="number">1</span> <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">5</span> <span class="number">8</span> <span class="number">13</span> <span class="number">21</span> <span class="number">34</span> <span class="number">55</span> <span class="number">89</span> <span class="number">144</span> <span class="number">233</span> <span class="number">377</span></span><br></pre></td></tr></table></figure><p>可以看到,新建的脚本文件中通过<code>import fibo</code>调用了开头写的斐波那契数列功能的模块。</p><p>当想要使用模块中的函数方法,仅需要用导入的模块名称加上”.功能函数名称”,就可以实现功能的调用甚至重新命名变量等操作。</p><h3 id="导入方式"><a href="#导入方式" class="headerlink" title="导入方式"></a>导入方式</h3><p>使用<code>import</code>导入包的方式现列出4种,例如:</p><ol><li><p>导入模块中的方法名称</p> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">>>> </span><span class="keyword">from</span> fibo <span class="keyword">import</span> fib, fib2</span><br><span class="line"><span class="meta">>>> </span>fib(<span class="number">500</span>)</span><br></pre></td></tr></table></figure></li><li><p>导入模块内定义的所有名称(不包括含<code>_</code>开头的名称,并且<strong>不建议</strong>使用这种方法导入)</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">>>> </span><span class="keyword">from</span> fibo <span class="keyword">import</span> *</span><br><span class="line"><span class="meta">>>> </span>fib(<span class="number">500</span>)</span><br><span class="line"><span class="number">0</span> <span class="number">1</span> <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">5</span> <span class="number">8</span> <span class="number">13</span> <span class="number">21</span> <span class="number">34</span> <span class="number">55</span> <span class="number">89</span> <span class="number">144</span> <span class="number">233</span> <span class="number">377</span></span><br></pre></td></tr></table></figure></li><li><p>模块名使用<code>as</code>,直接把<code>as</code>后的名称与导入模块绑定</p> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">>>> </span><span class="keyword">import</span> fibo <span class="keyword">as</span> fibo</span><br><span class="line"><span class="meta">>>> </span>fib.fib(<span class="number">500</span>)</span><br></pre></td></tr></table></figure></li><li><p>结合<code>from</code>一起使用</p> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">>>> </span><span class="keyword">from</span> fibo <span class="keyword">import</span> fib <span class="keyword">as</span> fibonacci</span><br><span class="line"><span class="meta">>>> </span>fibonacci(<span class="number">500</span>)</span><br></pre></td></tr></table></figure></li></ol><h3 id="以脚本方式运行模块"><a href="#以脚本方式运行模块" class="headerlink" title="以脚本方式运行模块"></a>以脚本方式运行模块</h3><p>通常在命令行执行脚本文件的语句:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python fibo.py <arguments></span><br></pre></td></tr></table></figure><p>直接运行<code>.py</code>脚本会在我们看不见的地方默认的执行一个事情,即:**把<code>__name__</code>赋值为<code>"__main__"</code>**。</p><p>也就是把下列代码添加到了模块的末尾</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line"> <span class="keyword">import</span> sys</span><br><span class="line"> fib(<span class="built_in">int</span>(sys.argv[<span class="number">1</span>]))</span><br></pre></td></tr></table></figure><p>这样做的含义是,在模块作为”main”文件(脚本)进行执行的时候才会运行。</p><p>举个例子:</p><ol><li><p>当模块作为脚本文件执行时(会执行):</p> <figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ python fibo.py 50</span><br><span class="line">0 1 1 2 3 5 8 13 21 34</span><br></pre></td></tr></table></figure></li><li><p>当模块被导入到其它模块或主程序时(不会执行):</p> <figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">>>> import fibo</span><br><span class="line">>>> </span><br></pre></td></tr></table></figure></li></ol><h3 id="Python文件的编译"><a href="#Python文件的编译" class="headerlink" title="Python文件的编译"></a>Python文件的编译</h3><p>这部分在官网文档讲解的非常清晰,参考<a href="https://docs.python.org/zh-cn/3/tutorial/modules.html#compiled-python-files">6.1.3. “已编译的” Python 文件</a></p><p>这里附上“Python模块快速加载”的决策细节流程图:</p><p><img src="https://s21.ax1x.com/2024/03/14/pFcXu5T.png" alt="pyc_flow_chart"></p><h3 id="使用内置函数dir-查看模型定义的名称"><a href="#使用内置函数dir-查看模型定义的名称" class="headerlink" title="使用内置函数dir()查看模型定义的名称"></a>使用内置函数dir()查看模型定义的名称</h3><p><code>dir()</code>用于查找模块定义的名称,返回值为排序之后的字符串列表。</p><p>上实例:</p><ol><li><p><code>dir()</code>含参数时:</p> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">>>> </span><span class="keyword">import</span> fibo, sys</span><br><span class="line"><span class="meta">>>> </span><span class="built_in">dir</span>(fibo)</span><br><span class="line">[<span class="string">'__name__'</span>, <span class="string">'fib'</span>, <span class="string">'fib2'</span>]</span><br><span class="line"><span class="meta">>>> </span><span class="built_in">dir</span>(sys)</span><br><span class="line">[<span class="string">'__breakpointhook__'</span>, <span class="string">'__displayhook__'</span>, <span class="string">'__doc__'</span>, <span class="string">'__excepthook__'</span>,</span><br><span class="line"> <span class="string">'__interactivehook__'</span>, <span class="string">'__loader__'</span>, <span class="string">'__name__'</span>, <span class="string">'__package__'</span>, <span class="string">'__spec__'</span>,</span><br><span class="line"> <span class="string">'__stderr__'</span>, <span class="string">'__stdin__'</span>, <span class="string">'__stdout__'</span>, <span class="string">'__unraisablehook__'</span>,</span><br><span class="line"> <span class="string">'_clear_type_cache'</span>, <span class="string">'_current_frames'</span>, <span class="string">'_debugmallocstats'</span>, <span class="string">'_framework'</span>,</span><br><span class="line"> <span class="string">'_getframe'</span>, <span class="string">'_git'</span>, <span class="string">'_home'</span>, <span class="string">'_xoptions'</span>, <span class="string">'abiflags'</span>, <span class="string">'addaudithook'</span>,</span><br><span class="line"> <span class="string">'api_version'</span>, <span class="string">'argv'</span>, <span class="string">'audit'</span>, <span class="string">'base_exec_prefix'</span>, <span class="string">'base_prefix'</span>,</span><br><span class="line"> <span class="string">'breakpointhook'</span>, <span class="string">'builtin_module_names'</span>, <span class="string">'byteorder'</span>, <span class="string">'call_tracing'</span>,</span><br><span class="line"> <span class="string">'callstats'</span>, <span class="string">'copyright'</span>, <span class="string">'displayhook'</span>, <span class="string">'dont_write_bytecode'</span>, <span class="string">'exc_info'</span>,</span><br><span class="line"> <span class="string">'excepthook'</span>, <span class="string">'exec_prefix'</span>, <span class="string">'executable'</span>, <span class="string">'exit'</span>, <span class="string">'flags'</span>, <span class="string">'float_info'</span>,</span><br><span class="line"> <span class="string">'float_repr_style'</span>, <span class="string">'get_asyncgen_hooks'</span>, <span class="string">'get_coroutine_origin_tracking_depth'</span>,</span><br><span class="line"> <span class="string">'getallocatedblocks'</span>, <span class="string">'getdefaultencoding'</span>, <span class="string">'getdlopenflags'</span>,</span><br><span class="line"> <span class="string">'getfilesystemencodeerrors'</span>, <span class="string">'getfilesystemencoding'</span>, <span class="string">'getprofile'</span>,</span><br><span class="line"> <span class="string">'getrecursionlimit'</span>, <span class="string">'getrefcount'</span>, <span class="string">'getsizeof'</span>, <span class="string">'getswitchinterval'</span>,</span><br><span class="line"> <span class="string">'gettrace'</span>, <span class="string">'hash_info'</span>, <span class="string">'hexversion'</span>, <span class="string">'implementation'</span>, <span class="string">'int_info'</span>,</span><br><span class="line"> <span class="string">'intern'</span>, <span class="string">'is_finalizing'</span>, <span class="string">'last_traceback'</span>, <span class="string">'last_type'</span>, <span class="string">'last_value'</span>,</span><br><span class="line"> <span class="string">'maxsize'</span>, <span class="string">'maxunicode'</span>, <span class="string">'meta_path'</span>, <span class="string">'modules'</span>, <span class="string">'path'</span>, <span class="string">'path_hooks'</span>,</span><br><span class="line"> <span class="string">'path_importer_cache'</span>, <span class="string">'platform'</span>, <span class="string">'prefix'</span>, <span class="string">'ps1'</span>, <span class="string">'ps2'</span>, <span class="string">'pycache_prefix'</span>,</span><br><span class="line"> <span class="string">'set_asyncgen_hooks'</span>, <span class="string">'set_coroutine_origin_tracking_depth'</span>, <span class="string">'setdlopenflags'</span>,</span><br><span class="line"> <span class="string">'setprofile'</span>, <span class="string">'setrecursionlimit'</span>, <span class="string">'setswitchinterval'</span>, <span class="string">'settrace'</span>, <span class="string">'stderr'</span>,</span><br><span class="line"> <span class="string">'stdin'</span>, <span class="string">'stdout'</span>, <span class="string">'thread_info'</span>, <span class="string">'unraisablehook'</span>, <span class="string">'version'</span>, <span class="string">'version_info'</span>,</span><br><span class="line"> <span class="string">'warnoptions'</span>]</span><br></pre></td></tr></table></figure></li><li><p><code>dir()</code>不含参数时:</p> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">>>> </span>a = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line"><span class="meta">>>> </span><span class="keyword">import</span> fibo</span><br><span class="line"><span class="meta">>>> </span>fib = fibo.fib</span><br><span class="line"><span class="built_in">dir</span>()</span><br><span class="line">[<span class="string">'__builtins__'</span>, <span class="string">'__name__'</span>, <span class="string">'a'</span>, <span class="string">'fib'</span>, <span class="string">'fibo'</span>, <span class="string">'sys'</span>]</span><br></pre></td></tr></table></figure></li></ol><h2 id="包"><a href="#包" class="headerlink" title="包"></a>包</h2><p>包是通过使用“<strong>带点号模块名</strong>”来构造 Python 模块命名空间的一种方式。</p><p>例如,模块名 <code>A.B</code> 表示名为 <code>A</code> 的包中名为 <code>B</code> 的子模块。</p><blockquote><p>使用<code>modules.func</code>的这种调用方式还有一个好处,就是避免在不同模块中的功能函数命名冲突。</p><p>例如:在 NumPy 或 Pillow 等多模块包中很多功能函数命名相同,这样使用<code>np.func</code>或<code>Pillow.func</code>就不必担心彼此的<code>func</code>模块名冲突了。</p></blockquote><p>假设要为统一处理声音文件与声音数据设计一个模块集(“包”)。声音文件的格式很多(通常以扩展名来识别,例如:<code>.wav</code>,<code>.aiff</code>,<code>.au</code>),因此,为了不同文件格式之间的转换,需要创建和维护一个不断增长的模块集合。</p><p>为了实现对声音数据的不同处理(例如,混声、添加回声、均衡器功能、创造人工立体声效果),还要编写无穷无尽的模块流。</p><p>下面这个分级文件树展示了这个包的架构:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">sound/ Top-level package</span><br><span class="line"> __init__.py Initialize the sound package</span><br><span class="line"> formats/ Subpackage for file format conversions</span><br><span class="line"> __init__.py</span><br><span class="line"> wavread.py</span><br><span class="line"> wavwrite.py</span><br><span class="line"> aiffread.py</span><br><span class="line"> aiffwrite.py</span><br><span class="line"> auread.py</span><br><span class="line"> auwrite.py</span><br><span class="line"> ...</span><br><span class="line"> effects/ Subpackage for sound effects</span><br><span class="line"> __init__.py</span><br><span class="line"> echo.py</span><br><span class="line"> surround.py</span><br><span class="line"> reverse.py</span><br><span class="line"> ...</span><br><span class="line"> filters/ Subpackage for filters</span><br><span class="line"> __init__.py</span><br><span class="line"> equalizer.py</span><br><span class="line"> vocoder.py</span><br><span class="line"> karaoke.py</span><br><span class="line"> ...</span><br></pre></td></tr></table></figure><p>导入包时,Python搜索<code>sys.path</code>里的目录,查找包的子目录。</p><p>需要有<code>__init__.py</code>文件才能让Python将包含改文件的目录当做“包”来处理。这样可以防止重名目录如<code>string</code>在无意中屏蔽后续出现在模块搜索路径中的有效模块。</p><p>最简单的情况就是,<code>__init__.py</code>可以是一个空文件,但是它也可以执行包的初始化代码或设置<code>__all__</code>变量,这将在稍后详细描述。</p><p>一些例子说明:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> sound.effects.echo</span><br><span class="line"></span><br><span class="line"><span class="comment"># 加载子模块 sound.effects.echo 必须通过全名来引用</span></span><br><span class="line">sound.effects.echo.echofilter(<span class="built_in">input</span>, output, delay)</span><br></pre></td></tr></table></figure><p>另一种导入子模块的方法:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sound.effects <span class="keyword">import</span> echo</span><br><span class="line"></span><br><span class="line"><span class="comment"># 加载子模块 echo,并且不必加包前缀</span></span><br><span class="line">echo.echofilter(<span class="built_in">input</span>, output, delay = <span class="number">0.7</span>, atten = <span class="number">4</span>)</span><br></pre></td></tr></table></figure><p>还有一种,直接导入所需的函数或变量:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sound.effect.echo <span class="keyword">import</span> echofilter</span><br><span class="line"></span><br><span class="line"><span class="comment"># 加载子模块 echo,使其函数 echofilter() 直接可用:</span></span><br><span class="line">echofilter(<span class="built_in">input</span>, output, delay = <span class="number">0.7</span>, atten = <span class="number">4</span>)</span><br></pre></td></tr></table></figure><h3 id="从包中导入"><a href="#从包中导入" class="headerlink" title="从包中导入*"></a>从包中导入*</h3><p>同理于模块的导入,同样不建议这样做。</p><p>一些需要提及的知识点:如果直接使用<code>*</code>进行导入,一般执行的操作为通过包中的<code>__init__.py</code>代码部分的以下<code>__all__</code>中的模块名列表。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">__all__ = [<span class="string">"echo"</span>, <span class="string">"surround"</span>, <span class="string">"reverse"</span>]</span><br></pre></td></tr></table></figure><p><strong>子模块的命名有可能会受到本地定义名称的影响!</strong></p><p>模块中的模块如果和环境中已存在的模块重名,则会被本地<strong>先</strong>定义过的函数名称遮挡。以<code>reverse</code>函数为例:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">__all__ = [</span><br><span class="line"> <span class="string">"echo"</span>, <span class="comment"># refers to the 'echo.py' file</span></span><br><span class="line"> <span class="string">"surround"</span>, <span class="comment"># refers to the 'surround.py' file</span></span><br><span class="line"> <span class="string">"reverse"</span>, <span class="comment"># !!! refers to the 'reverse' function now !!!</span></span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">reverse</span>(<span class="params">msg: <span class="built_in">str</span></span>): <span class="comment"># <-- this name shadows the 'reverse.py' submodule</span></span><br><span class="line"> <span class="keyword">return</span> msg[::-<span class="number">1</span>] <span class="comment"># in the case of a 'from sound.effects import *'</span></span><br></pre></td></tr></table></figure><p>官方文档中,推荐的做法是:<code>frome package import submodule</code>.</p><h3 id="相对导入"><a href="#相对导入" class="headerlink" title="相对导入"></a>相对导入</h3><p>当包由多个子包构成(如示例中的 <code>sound</code> 包)时,可以使用绝对导入来引用同级包的子模块。</p><p>例如,如果 <code>sound.filters.vocoder</code> 模块需要使用 <code>sound.effects</code> 包中的 <code>echo</code> 模块,它可以使用 <code>from sound.effects import echo</code>。</p><p>你还可以编写相对导入代码,即使用 <code>from module import name</code> 形式的 import 语句。</p><p>这些导入使用<strong>前导点号</strong>来表示相对导入所涉及的当前包和上级包。</p><p>例如对于 <code>surround</code> 模块,可以使用:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> . <span class="keyword">import</span> echo</span><br><span class="line"><span class="keyword">from</span> .. <span class="keyword">import</span> formats</span><br><span class="line"><span class="keyword">from</span> ..filters <span class="keyword">import</span> equalizer</span><br></pre></td></tr></table></figure><p><strong>注意,相对导入基于当前模块名。</strong></p><p>因为主模块名永远是 <code>"__main__"</code> ,所以如果计划将一个模块用作 Python 应用程序的主模块,那么该模块内的导入语句必须始终使用绝对导入。</p><h3 id="多目录中的包"><a href="#多目录中的包" class="headerlink" title="多目录中的包"></a>多目录中的包</h3><p>通过 <a href="https://docs.python.org/zh-cn/3/reference/import.html#path">__path__</a> 可以传入字符串列表,找到所有 <code>__init__.py</code>坐在目录的位置。该功能不常用,知道就好。</p><hr><p>相关参考:</p><ul><li><a href="https://docs.python.org/zh-cn/3/tutorial/modules.html#">6. 模块 — Python 3.12.2 文档</a></li></ul>]]></content>
<summary type="html"><ul>
<li><a href="#%E8%83%8C%E6%99%AF%E4%BB%8B%E7%BB%8D">背景介绍</a></li>
<li><a href="#tldr">TL;DR</a></li>
<li><a href="#%E6%A8%A1%E5%9D%97"></summary>
<category term="Python" scheme="https://zade23.github.io/tags/Python/"/>
</entry>
<entry>
<title>【Git】合作开发中Git工作流程的细节</title>
<link href="https://zade23.github.io/2024/03/11/%E3%80%90Git%E3%80%91%E5%90%88%E4%BD%9C%E5%BC%80%E5%8F%91%E4%B8%ADGit%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B%E7%9A%84%E7%BB%86%E8%8A%82/"/>
<id>https://zade23.github.io/2024/03/11/%E3%80%90Git%E3%80%91%E5%90%88%E4%BD%9C%E5%BC%80%E5%8F%91%E4%B8%ADGit%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B%E7%9A%84%E7%BB%86%E8%8A%82/</id>
<published>2024-03-11T08:39:05.000Z</published>
<updated>2024-12-17T03:45:00.013Z</updated>
<content type="html"><![CDATA[<ul><li><a href="#%E4%BB%93%E5%BA%93%E4%B8%AD%E5%90%84%E5%88%86%E6%94%AF%E7%9A%84%E8%81%8C%E8%B4%A3">仓库中各分支的职责</a></li><li><a href="#%E6%B8%85%E6%99%B0%E7%9A%84commit">清晰的Commit</a></li></ul><hr><p>记录开发过程中,提交代码仓库的一些经验总结(持续更新……)</p><h3 id="仓库中各分支的职责"><a href="#仓库中各分支的职责" class="headerlink" title="仓库中各分支的职责"></a>仓库中各分支的职责</h3><ol><li><p><strong>master分支</strong>:master分支是存放发布上线的代码的默认位置。当某个功能经过验证和测试后,将develop分支合并到master分支,并为该版本打上相应的标签(例如x.0.0,表示某个大版本的编号)。master分支应该是稳定且经过充分测试的代码。</p></li><li><p><strong>develop分支</strong>:develop分支是整体开发功能的主要分支。在开发阶段,所有功能的开发工作都应提交到develop分支。在功能开发完成后,通过测试和验证后,将develop分支合并到master分支,使功能正式上线。</p></li></ol><blockquote><p>扩展:</p><ul><li>除了master和develop分支外,还可以存在其他类型的分支,如<strong>feature</strong>分支、<strong>bugfix</strong>分支等。这些分支可以用于并行开发不同的功能或修复bug,并在开发完成后合并到develop分支。</li><li>开发团队通常采用分支策略,例如Git Flow或GitHub Flow,来管理不同分支之间的合并和发布流程,以确保代码质量和版本控制的有效管理。</li><li>主分支(如master或main)通常用于存放稳定的、可发布的代码,而开发分支(如develop)则用于整体功能的开发和集成。</li><li>通过使用不同的分支,可以实现并行开发、合理管理代码版本、隔离功能开发和修复等,从而提高团队的协作效率和代码质量。</li><li>重要的是,分支之间的合并应该经过适当的测试和验证,以确保代码的稳定性和功能的正确性。</li></ul></blockquote><h3 id="清晰的Commit"><a href="#清晰的Commit" class="headerlink" title="清晰的Commit"></a>清晰的Commit</h3><ol><li><strong>使用明确的动词</strong>:在提交信息的开头使用明确的动词来描述你的更改。例如,使用 “添加”、”修复”、”更新”、”重构” 等词语,以便其他人可以快速了解你的更改类型。</li><li><strong>保持简洁</strong>:提交信息应该简洁明了,尽量避免冗长的描述。使用简洁的语句来概括你的更改,并在需要时提供详细信息。</li><li><strong>提供相关上下文</strong>:除了简洁的概述外,确保提交信息提供足够的上下文信息,以便其他人能够理解你的更改原因和意图。如果有相关的问题、需求或讨论,可以引用相关的编号或链接。</li><li><strong>遵循团队或项目规范</strong>:根据你所在的团队或项目的规范,使用统一的提交格式和命名约定。这样可以帮助整个团队保持一致的提交信息风格,便于阅读和管理。</li><li><strong>避免无意义的提交信息</strong>:提交信息应该有实际的意义,避免使用模糊或不相关的描述。确保你的提交信息传达了有用的信息,而不仅仅是表明你进行了一次提交。</li><li><strong>使用标准的提交类型</strong>:参考常见的提交类型(如前面所示),选择最适合你更改类型的提交类型。这有助于其他人快速了解你的更改类型,并且在版本控制工具中进行过滤和分类。</li><li><strong>审查和校对</strong>:在提交之前,花一些时间审查和校对你的提交信息。确保拼写正确、语法清晰,并且信息准确传达你的更改。</li></ol><p>常见的提交格式实例:</p><p>当然,以下是一些常见的提交格式示例:</p><ol><li><p><strong>feat</strong>: 添加新功能或特性</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">feat: 添加用户注册功能</span><br></pre></td></tr></table></figure></li><li><p><strong>fix</strong>: 修复 bug</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fix: 修复登录页面样式错位的 bug</span><br></pre></td></tr></table></figure></li><li><p><strong>docs</strong>: 更新文档</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docs: 更新用户手册中的安装说明</span><br></pre></td></tr></table></figure></li><li><p><strong>style</strong>: 代码样式、格式调整</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">style: 格式化整个项目的代码风格</span><br></pre></td></tr></table></figure></li><li><p><strong>refactor</strong>: 重构代码,既不修复 bug 也不添加新功能</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">refactor: 重构用户管理模块的代码结构</span><br></pre></td></tr></table></figure></li><li><p><strong>test</strong>: 添加或修改测试代码</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">test: 添加用户注册页面的单元测试</span><br></pre></td></tr></table></figure></li><li><p><strong>chore</strong>: 构建过程或辅助工具的变动</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">chore: 更新构建脚本以支持新的依赖库</span><br></pre></td></tr></table></figure></li></ol><p>这一切的目的是为了让团队其他成员明确该提交所做的工作,同时也让自己回顾代码的时候明确自己的工作内容。</p>]]></content>
<summary type="html"><ul>
<li><a href="#%E4%BB%93%E5%BA%93%E4%B8%AD%E5%90%84%E5%88%86%E6%94%AF%E7%9A%84%E8%81%8C%E8%B4%A3">仓库中各分支的职责</a></li>
<li><a href="#%E6%B</summary>
<category term="Git Workflow" scheme="https://zade23.github.io/categories/Git-Workflow/"/>
<category term="Git" scheme="https://zade23.github.io/tags/Git/"/>
</entry>
<entry>
<title>更新GitLab仓库SSH</title>
<link href="https://zade23.github.io/2024/03/07/%E6%9B%B4%E6%96%B0GitLab%E4%BB%93%E5%BA%93SSH/"/>
<id>https://zade23.github.io/2024/03/07/%E6%9B%B4%E6%96%B0GitLab%E4%BB%93%E5%BA%93SSH/</id>
<published>2024-03-07T02:09:37.000Z</published>
<updated>2024-03-11T08:41:35.516Z</updated>
<content type="html"><![CDATA[<ul><li><a href="#%E4%BB%8B%E7%BB%8D">介绍</a></li><li><a href="#%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90">问题分析</a></li><li><a href="#%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3">问题解决</a></li></ul><h3 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h3><p>早上开工,在拉取代码仓库的时候,发现SSH过期,于是更新一下SSH为永久,并做一个记录。SSH过期命令行显示如下:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">$ git pull</span><br><span class="line">remote:</span><br><span class="line">remote: ========================================================================</span><br><span class="line">remote:</span><br><span class="line">remote: Your SSH key has expired.</span><br><span class="line">remote:</span><br><span class="line">remote: ========================================================================</span><br><span class="line">remote:</span><br><span class="line">fatal: Could not <span class="built_in">read</span> from remote repository.</span><br><span class="line"></span><br><span class="line">Please make sure you have the correct access rights</span><br><span class="line">and the repository exists.</span><br></pre></td></tr></table></figure><h3 id="问题分析"><a href="#问题分析" class="headerlink" title="问题分析"></a>问题分析</h3><p>直接将问题送给poe,让AI分析解答,根据分析结果一步步处理即可解决。结果如下:</p><p><a href="https://imgse.com/i/pFr02Yn"><img src="https://s21.ax1x.com/2024/03/07/pFr02Yn.png" alt="pFr02Yn.png"></a></p><h3 id="问题解决"><a href="#问题解决" class="headerlink" title="问题解决"></a>问题解决</h3><ol><li><p>生成新的SSH密码对。<code>ssh-keygen -t rsa -b 4096 -C "[email protected]"</code>,该命令将生成一个 4096 位的 RSA 密钥对,替换邮箱地址为你GitLab注册邮箱。</p></li><li><p>之后会有两次询问你保存位置和输入密码的选项,点击 Enter 键跳过选项即可。显示结果如下:</p><p> <a href="https://imgse.com/i/pFr0XSx"><img src="https://s21.ax1x.com/2024/03/07/pFr0XSx.png" alt="pFr0XSx.png"></a></p></li><li><p>复制生成的SSH,window使用:</p> <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">clip < ~/.ssh/id_rsa.pub</span><br></pre></td></tr></table></figure></li><li><p>找到GitLab中的SSH Keys一栏,粘贴,保存:<br> <a href="https://imgse.com/i/pFrBZX8"><img src="https://s21.ax1x.com/2024/03/07/pFrBZX8.png" alt="pFrBZX8.png"></a></p></li><li><p>可以拉取仓库了</p></li></ol>]]></content>
<summary type="html"><ul>
<li><a href="#%E4%BB%8B%E7%BB%8D">介绍</a></li>
<li><a href="#%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90">问题分析</a></li>
<li><a href="#%E9%97%AE</summary>
<category term="Git Workflow" scheme="https://zade23.github.io/categories/Git-Workflow/"/>
<category term="Git" scheme="https://zade23.github.io/tags/Git/"/>
</entry>
<entry>
<title>conda环境报错解决:invalid choice: 'activate' </title>
<link href="https://zade23.github.io/2023/11/22/conda%E7%8E%AF%E5%A2%83%E6%8A%A5%E9%94%99%E8%A7%A3%E5%86%B3%EF%BC%9Ainvalid-choice-activate/"/>
<id>https://zade23.github.io/2023/11/22/conda%E7%8E%AF%E5%A2%83%E6%8A%A5%E9%94%99%E8%A7%A3%E5%86%B3%EF%BC%9Ainvalid-choice-activate/</id>
<published>2023-11-22T08:04:41.000Z</published>
<updated>2024-03-14T03:02:38.054Z</updated>
<content type="html"><![CDATA[<h3 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h3><p>新部署的服务器上进行LLM模型的微调工作,在配置Anaconde环境后输入环境启动命令 <code>conda activate</code> ,出现从来没有见过的报错:<code>anaconda conda: error: argument command: invalid choice when trying to update packages</code></p><h3 id="问题分析"><a href="#问题分析" class="headerlink" title="问题分析"></a>问题分析</h3><p>环境问题,直接Google。最终在 GitHub 里<a href="https://github.com/conda/conda/issues/13022">官方仓库</a>和 <a href="https://stackoverflow.com/questions/53995171/anaconda-conda-error-argument-command-invalid-choice-when-trying-to-update-pa">Stack Overflow</a> 上找到一致的答复:安装Anaconde后没有进行初始化。</p><h3 id="问题解决"><a href="#问题解决" class="headerlink" title="问题解决"></a>问题解决</h3><ol><li><p>终端运行 <code>conda init zsh</code></p></li><li><p>之后重启 shell/Terminal (不重启依然报错)</p></li><li><p>终端运行 <code>conda activate env_name</code> 即可</p></li></ol>]]></content>
<summary type="html"><h3 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h3><p>新部署的服务器上进行LLM模型的微调工作,在配置Anaconde环境后输入环境启动命令 <code>conda activate</code</summary>
<category term="Deeplearning" scheme="https://zade23.github.io/categories/Deeplearning/"/>
<category term="conda" scheme="https://zade23.github.io/tags/conda/"/>
<category term="environment" scheme="https://zade23.github.io/tags/environment/"/>
</entry>
</feed>