forked from chenzomi12/AISystem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path09.srt
696 lines (522 loc) · 11 KB
/
09.srt
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
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
1
00:00:00,000 --> 00:00:05,000
字幕生成:qiaokai 字幕校对:mkwei
2
00:00:06,466 --> 00:00:09,133
嗨大家早上好我是ZOMI
3
00:00:09,200 --> 00:00:10,600
那在这一节里面呢
4
00:00:10,600 --> 00:00:14,100
还是在AI编译器里面的前端优化
5
00:00:14,366 --> 00:00:16,333
今天我要给大家汇报的内容呢
6
00:00:16,333 --> 00:00:18,333
叫做死代码消除
7
00:00:18,400 --> 00:00:22,166
那死代码消除的缩写叫做DCE
8
00:00:22,300 --> 00:00:24,133
Dead Code Elimination
9
00:00:25,400 --> 00:00:27,766
今天我主要分开两个内容给大家
10
00:00:27,766 --> 00:00:28,699
去汇报的
11
00:00:28,700 --> 00:00:31,266
第一个呢就是DCE的概念的定义
12
00:00:31,266 --> 00:00:31,699
第二个呢
13
00:00:31,700 --> 00:00:35,400
就是AI编译器里面的DCE是怎么实现的
14
00:00:35,500 --> 00:00:37,800
事不宜辞马上开始
15
00:00:42,733 --> 00:00:43,766
首先第一个内容呢
16
00:00:43,766 --> 00:00:44,399
就是
17
00:00:44,400 --> 00:00:47,266
死代码消除DCE的一个概念的定义
18
00:00:47,566 --> 00:00:49,866
那死代码呢其实很简单了
19
00:00:49,866 --> 00:00:50,666
理解一下
20
00:00:50,666 --> 00:00:53,133
这里面呢有一段简单的代码
21
00:00:53,133 --> 00:00:54,333
一个foo的函数
22
00:00:54,400 --> 00:00:55,333
那看一下
23
00:00:55,333 --> 00:00:57,299
这个函数里面实现了哪些功能
24
00:00:57,300 --> 00:00:58,600
首先定义一个a
25
00:00:58,700 --> 00:00:59,700
再定义一个b
26
00:00:59,800 --> 00:01:01,066
接着呢定义一个c
27
00:01:01,300 --> 00:01:04,533
然后呢c是通过a来去做一个移位的
28
00:01:04,533 --> 00:01:07,399
然后现在呢去返回一个return c
29
00:01:07,766 --> 00:01:10,766
接着我又对b进行一个重新的赋值
30
00:01:10,766 --> 00:01:11,899
最后返回0
31
00:01:12,166 --> 00:01:14,533
在第8行的时候我已经return c了
32
00:01:14,533 --> 00:01:16,666
所以这里面的函数已经结束
33
00:01:16,900 --> 00:01:19,366
第9行对b进行重新赋值
34
00:01:19,400 --> 00:01:22,500
这一句话呢是不会被程序所执行的
35
00:01:22,500 --> 00:01:25,100
所以这一句呢叫做死代码
36
00:01:25,300 --> 00:01:26,500
在编译器里面呢
37
00:01:26,500 --> 00:01:29,666
需要把这个第九行和第十行去掉
38
00:01:29,666 --> 00:01:31,933
因为它是没有任何意义的
39
00:01:33,300 --> 00:01:34,166
一般来说呢
40
00:01:34,166 --> 00:01:36,366
死代码消除最普遍的方法呢
41
00:01:36,366 --> 00:01:37,799
是通过预处理器
42
00:01:37,800 --> 00:01:39,800
来判断代码是否需要被编译
43
00:01:39,800 --> 00:01:40,800
或者执行
44
00:01:40,933 --> 00:01:42,766
那所谓的预处理器呢
45
00:01:42,766 --> 00:01:44,599
就是通过代入一个数
46
00:01:44,600 --> 00:01:46,166
来决定这段程序
47
00:01:46,166 --> 00:01:47,366
是否被执行
48
00:01:47,666 --> 00:01:50,766
假设我用下面这么一段函数赋值了a b c
49
00:01:50,766 --> 00:01:53,266
然后c呢进行一个处理
50
00:01:53,300 --> 00:01:55,366
接着我去判断一个if(0)
51
00:01:55,366 --> 00:01:57,266
然后print一句话出来
52
00:01:57,500 --> 00:01:59,933
这个if(0)呢0默认是False
53
00:01:59,933 --> 00:02:01,866
所以他一般是执行不了的
54
00:02:01,866 --> 00:02:04,066
那789他就是一个死代码
55
00:02:04,366 --> 00:02:05,499
在第7行的时候呢
56
00:02:05,500 --> 00:02:08,000
就会通过一个预先设置的值
57
00:02:08,000 --> 00:02:10,766
来判断这段程序呢是否会被执行
58
00:02:10,766 --> 00:02:13,199
像789也是一段死代码
59
00:02:14,966 --> 00:02:16,199
哎ZOMI老师你好
60
00:02:16,200 --> 00:02:18,400
为什么要做死代码消除呢
61
00:02:18,566 --> 00:02:20,733
嗯这个问题很有意思看一下
62
00:02:20,766 --> 00:02:23,066
首先呢做死代码消除就是避免
63
00:02:23,066 --> 00:02:24,733
在真正执行的时候
64
00:02:24,733 --> 00:02:27,533
执行一些没有必要没有意义的操作
65
00:02:27,700 --> 00:02:29,933
提高了整体的运算的效率
66
00:02:29,933 --> 00:02:32,266
减少运算的开销和时间
67
00:02:32,266 --> 00:02:34,266
那这个是它最重要的作用
68
00:02:34,300 --> 00:02:36,866
第二个呢就是节省不必要的资源分配
69
00:02:36,866 --> 00:02:37,766
优化空间
70
00:02:37,966 --> 00:02:39,899
可以看到刚才那段程序呢
71
00:02:40,066 --> 00:02:41,399
b他是赋值了
72
00:02:41,400 --> 00:02:42,133
但实际上啊
73
00:02:42,133 --> 00:02:44,333
他没有必要去从内存里面去读
74
00:02:44,333 --> 00:02:46,733
也没有必要去存b这一个变量
75
00:02:46,766 --> 00:02:49,266
那最后呢就是节省代码的长度
76
00:02:49,266 --> 00:02:50,466
增加可读性
77
00:02:50,466 --> 00:02:53,499
把一些没有用的冗余的代码给他删掉
78
00:02:55,300 --> 00:02:58,000
下面看看AI编译器里面的死代码消除
79
00:02:58,000 --> 00:02:59,166
是怎么实现的
80
00:02:59,200 --> 00:03:02,800
AI编译器呢最主要的输入呢是计算图
81
00:03:03,366 --> 00:03:05,966
AI编译器最主要的输入呢是计算图
82
00:03:05,966 --> 00:03:07,533
所以死代码消除呢
83
00:03:07,533 --> 00:03:09,466
可以优化计算图的计算和
84
00:03:09,466 --> 00:03:10,266
存储效率
85
00:03:10,266 --> 00:03:12,399
就减少计算图里面的节点
86
00:03:12,733 --> 00:03:15,466
存一些更小的变量或者权重参数
87
00:03:16,966 --> 00:03:17,899
整体上来说呢
88
00:03:17,900 --> 00:03:19,733
是简化整个计算图的结构
89
00:03:19,733 --> 00:03:21,866
方便后续的其他优化的
90
00:03:21,900 --> 00:03:23,333
pass去进行的
91
00:03:23,533 --> 00:03:24,966
那其实有一点很
92
00:03:24,966 --> 00:03:27,666
重要的就是死代码消除一般不是在
93
00:03:27,766 --> 00:03:30,366
定义神经网络模型的时候所引起的
94
00:03:30,500 --> 00:03:31,500
这句话的意思就是
95
00:03:31,500 --> 00:03:33,600
算法工程师其实没那么傻
96
00:03:33,600 --> 00:03:35,500
写那么多没有用的代码
97
00:03:35,700 --> 00:03:36,700
这些死代码呢
98
00:03:36,700 --> 00:03:38,933
一般来说是其他图优化的pass
99
00:03:39,000 --> 00:03:40,100
所造成的
100
00:03:40,333 --> 00:03:42,899
因此呢死代码消除这个pass呢
101
00:03:42,900 --> 00:03:43,966
一般都会放在
102
00:03:43,966 --> 00:03:46,666
其他图优化的pass后面去执行
103
00:03:48,866 --> 00:03:51,766
左边这个就是计算图里面的一部分
104
00:03:51,766 --> 00:03:53,599
现在呢有三个算子
105
00:03:53,600 --> 00:03:55,800
一个是Op2 Op3和Op4
106
00:03:55,866 --> 00:03:58,599
它的输入呢有两个一个是a和b
107
00:03:59,133 --> 00:04:01,099
假设Op3最后的输出呢
108
00:04:01,100 --> 00:04:02,933
是对于神经网络图里面的
109
00:04:02,933 --> 00:04:03,866
最后的输出
110
00:04:03,966 --> 00:04:06,799
而Op4呢它就没有了任何输出
111
00:04:06,800 --> 00:04:09,133
就它到这个节点之后就停止了
112
00:04:09,133 --> 00:04:09,666
这个时候呢
113
00:04:09,666 --> 00:04:11,466
可以认为输入的张量b
114
00:04:11,566 --> 00:04:13,166
还有Op4算子呢
115
00:04:13,166 --> 00:04:16,333
它其实对应计算图里面的死代码
116
00:04:16,466 --> 00:04:18,366
于是呢就可以把它干掉
117
00:04:18,366 --> 00:04:20,299
可以对这个计算图进行优化
118
00:04:20,300 --> 00:04:22,266
最后变成右边的这个图
119
00:04:22,266 --> 00:04:23,766
只有两个算子
120
00:04:23,800 --> 00:04:25,333
两个输入的张量
121
00:04:27,266 --> 00:04:28,899
下面值得重点去提一提
122
00:04:28,900 --> 00:04:30,133
或者我之前踩过的坑
123
00:04:30,133 --> 00:04:32,766
就是在网络模型训练的时候
124
00:04:32,766 --> 00:04:34,666
跟网络模型推理的时候
125
00:04:35,166 --> 00:04:36,699
除了反向图没有用
126
00:04:36,700 --> 00:04:38,933
要删除反向图之外呢
127
00:04:39,000 --> 00:04:41,766
训练的时候呢会产生很多额外的子图
128
00:04:41,766 --> 00:04:42,499
那这个时候呢
129
00:04:42,500 --> 00:04:44,466
转换成为推理的时候呢
130
00:04:44,466 --> 00:04:46,199
也会执行死代码消除
131
00:04:46,200 --> 00:04:47,700
把训练的时候用到
132
00:04:47,700 --> 00:04:49,066
但是推理的时候呢
133
00:04:49,066 --> 00:04:52,566
没有用到的一些子图死代码把它删掉
134
00:04:54,066 --> 00:04:55,399
第二个值得注意的就是
135
00:04:55,400 --> 00:04:57,866
有一些没有用的控制流也会对
136
00:04:57,866 --> 00:04:59,366
它进行删掉
137
00:05:00,966 --> 00:05:01,333
最后呢
138
00:05:01,333 --> 00:05:03,966
看一下死代码消除的一个最简单
139
00:05:03,966 --> 00:05:05,699
的算法那第一步呢
140
00:05:05,700 --> 00:05:08,500
输入的是计算图的IR
141
00:05:09,133 --> 00:05:09,599
第二步呢
142
00:05:09,600 --> 00:05:11,266
就是对计算图进行
143
00:05:11,266 --> 00:05:12,566
深度优先遍历
144
00:05:12,566 --> 00:05:13,733
那深度优先遍历呢
145
00:05:13,733 --> 00:05:15,566
从输出节点出发
146
00:05:15,566 --> 00:05:17,733
去获取逆后续节点
147
00:05:17,866 --> 00:05:19,966
接着呢去遍历这个逆后续节点
148
00:05:19,966 --> 00:05:22,533
去判断有没有死代码
149
00:05:22,766 --> 00:05:25,099
如果有的话就把这个死代码删掉
150
00:05:25,100 --> 00:05:26,866
重新去执行步骤一
151
00:05:26,866 --> 00:05:29,966
这个就是最简单最原始最naive的算法
152
00:05:31,800 --> 00:05:33,733
接着呢看两个值得注意的点
153
00:05:33,733 --> 00:05:34,933
就是可以通过
154
00:05:34,933 --> 00:05:36,299
迭代式的深度优先遍历
155
00:05:36,300 --> 00:05:38,933
就DFS呢去找到死代码
156
00:05:38,933 --> 00:05:40,299
或者叫做死节点
157
00:05:40,300 --> 00:05:43,066
就类似于Op4还有张量b
158
00:05:44,600 --> 00:05:45,866
另外呢可以建立
159
00:05:45,866 --> 00:05:47,666
节点使用的一个拓扑序列
160
00:05:47,666 --> 00:05:50,066
就标明Op4被什么使用了
161
00:05:50,066 --> 00:05:51,799
我的张量b被什么使用了
162
00:05:51,800 --> 00:05:53,166
如果他没有被使用
163
00:05:53,166 --> 00:05:56,199
或者他Op4呢没有被输出节点引用
164
00:05:56,266 --> 00:05:58,399
Op4的使用的次数呢就是0
165
00:05:58,400 --> 00:06:00,366
那这个时候我可以把Op4
166
00:06:00,966 --> 00:06:03,399
删掉然后再把张量删掉
167
00:06:04,100 --> 00:06:06,600
通过鉴定使用的拓扑也可以实现
168
00:06:06,600 --> 00:06:09,300
所以死代码消除的算法呢有很多
169
00:06:09,666 --> 00:06:12,999
具体取决于怎么高效的去实现
170
00:06:13,200 --> 00:06:14,600
好了谢谢各位
171
00:06:14,800 --> 00:06:16,533
卷的不行了卷的不行了
172
00:06:16,533 --> 00:06:18,299
记得一键三连加关注哦
173
00:06:18,333 --> 00:06:19,699
所有的内容都会开源
174
00:06:19,700 --> 00:06:22,666
在下面这条链接里面拜了个拜