forked from chenzomi12/AISystem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path07.srt
1327 lines (996 loc) · 22 KB
/
07.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
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1
00:00:01,250 --> 00:00:04,250
字幕组:赵含霖 谢鑫鑫
2
00:00:04,775 --> 00:00:06,720
Hello,大家好,我是ZOMI
3
00:00:06,720 --> 00:00:09,520
今天又是一节没什么人来观看
4
00:00:09,520 --> 00:00:13,320
但是我依然在坚持的一节分享课里面
5
00:00:13,320 --> 00:00:18,320
今天主要是给大家去聊一聊自动微分的一个挑战和未来
6
00:00:18,320 --> 00:00:22,880
自动微分这个话题其实已经过了非常多的内容了
7
00:00:22,880 --> 00:00:26,080
包括从自动微分的一个基础的概念
8
00:00:26,080 --> 00:00:27,840
那有哪几种微分呢?
9
00:00:27,840 --> 00:00:31,520
在计算机表达里面就有三种的微分模式
10
00:00:31,520 --> 00:00:35,960
然后实际上模式又有前向微分和后向微分
11
00:00:35,960 --> 00:00:40,760
具体的实现过程又分别有表达式、图、操作符重载
12
00:00:40,760 --> 00:00:42,520
还有源码转换
13
00:00:42,520 --> 00:00:45,040
那在具体的实现或者代码实现
14
00:00:45,040 --> 00:00:48,040
其实用了操作符重载的这种方式
15
00:00:48,040 --> 00:00:51,240
去表达了正向和后向怎么实现的
16
00:00:51,240 --> 00:00:54,920
既然讲完所有关于自动微分的具体实现
17
00:00:55,040 --> 00:00:56,480
面向这些
18
00:00:57,240 --> 00:00:59,600
面向自动微分的实现
19
00:00:59,600 --> 00:01:03,080
其实还有很多挑战和未来可以聊一聊的
20
00:01:03,360 --> 00:01:06,600
首先第一个最大的就是易用性问题
21
00:01:07,200 --> 00:01:11,840
可以看到左边这个就是一些数学的表示
22
00:01:11,840 --> 00:01:15,520
需要对数学的表示通过计算机系统
23
00:01:15,520 --> 00:01:17,880
变成可编程的语言
24
00:01:17,880 --> 00:01:19,520
就是右边的这一坨
25
00:01:19,800 --> 00:01:24,040
但是看到左边的这个是理想的情况
26
00:01:24,040 --> 00:01:27,240
理想的情况就是对数学进行表达
27
00:01:27,240 --> 00:01:31,880
对数学的公式进行分解微分组合的这么一个过程
28
00:01:32,200 --> 00:01:33,720
但是右边可以看到
29
00:01:33,720 --> 00:01:36,240
其实已经把数学过程变成一个遍历
30
00:01:36,240 --> 00:01:37,200
变成一个for
31
00:01:37,200 --> 00:01:39,840
变成一个实际的程序表达
32
00:01:39,840 --> 00:01:43,240
所以自动微分系统或者AI框架
33
00:01:43,240 --> 00:01:46,160
实际上并不是对数学进行表达
34
00:01:46,160 --> 00:01:50,120
而是对程序或者代码进行表达
35
00:01:50,160 --> 00:01:54,200
这个时候就会引起大量的编程的易用性问题
36
00:01:54,200 --> 00:01:57,400
或者程序员编写代码习惯性的问题
37
00:01:59,600 --> 00:02:01,680
说到编程的习惯问题
38
00:02:02,160 --> 00:02:05,120
下面就继续详细的展开一下
39
00:02:05,120 --> 00:02:07,560
第一个就是控制流表达
40
00:02:07,560 --> 00:02:10,520
这个是作为易用性的第一条
41
00:02:10,520 --> 00:02:12,480
可以看到左边的公式
42
00:02:12,640 --> 00:02:14,680
还是刚才熟悉的味道
43
00:02:15,800 --> 00:02:18,000
分别是l(n+1)=4l(n)(l-l(1))
44
00:02:18,040 --> 00:02:20,560
就是做一个自闭包的一个函数
45
00:02:20,560 --> 00:02:23,840
那右边实际上对程序进行表达
46
00:02:24,200 --> 00:02:26,320
变成一个for i等于1
47
00:02:26,320 --> 00:02:30,160
to 3这么一个简单的三次循环
48
00:02:30,160 --> 00:02:32,400
然后再把v返回出来
49
00:02:32,760 --> 00:02:36,960
这个时候AI框架就要求程序去识别
50
00:02:36,960 --> 00:02:41,600
除了if else while这些控制流部分的程序
51
00:02:41,800 --> 00:02:45,000
然后将其排除在微分的过程当中
52
00:02:45,000 --> 00:02:46,640
才能进行很好的微分
53
00:02:46,640 --> 00:02:47,160
对吧
54
00:02:47,160 --> 00:02:49,360
所以控制流进行表达的时候
55
00:02:49,360 --> 00:02:51,920
就会引起各种副作用的问题
56
00:02:54,240 --> 00:02:58,320
第二点就是数据类型非常复杂
57
00:02:58,480 --> 00:03:00,080
在计算机系统里面
58
00:03:00,360 --> 00:03:03,000
除了经常看到的数据类型
59
00:03:03,000 --> 00:03:06,040
int float double这些数据类型以外
60
00:03:06,040 --> 00:03:06,840
还有char
61
00:03:09,000 --> 00:03:11,920
第二点就是复杂的数据类型
62
00:03:12,280 --> 00:03:14,480
在实际语言表达的时候
63
00:03:14,720 --> 00:03:15,800
还有BOOLEAN
64
00:03:15,800 --> 00:03:16,480
还有List
65
00:03:16,480 --> 00:03:17,600
Enum,Tuple
66
00:03:17,600 --> 00:03:18,360
Dict
67
00:03:18,360 --> 00:03:19,120
还有list
68
00:03:19,120 --> 00:03:22,640
很多不同的一些复杂的数据结构
69
00:03:22,800 --> 00:03:25,480
如何对这些数据结构进行微分呢
70
00:03:25,920 --> 00:03:27,840
在前面的章节里面
71
00:03:27,840 --> 00:03:30,200
根本没有去介绍面向不同
72
00:03:30,200 --> 00:03:32,600
复杂的数据类型进行微分
73
00:03:32,720 --> 00:03:34,760
只是把它当成一个数值
74
00:03:34,760 --> 00:03:36,600
然后对数值或者对
75
00:03:36,600 --> 00:03:38,880
基本的数学公式进行微分
76
00:03:39,000 --> 00:03:41,360
所以同样AI框架
77
00:03:41,560 --> 00:03:44,240
还要排除掉复杂的数据类型
78
00:03:44,280 --> 00:03:47,760
然后对最原始的数据表达进行微分
79
00:03:48,880 --> 00:03:51,480
这就是应用性引起的第二个问题
80
00:03:51,480 --> 00:03:52,840
复杂数据类型
81
00:03:54,520 --> 00:03:57,840
第三个应用性问题就是语言特性了
82
00:03:57,960 --> 00:03:59,200
刚才也
83
00:03:59,280 --> 00:04:01,280
在上一节里面也说了
84
00:04:01,280 --> 00:04:02,760
实现自动微分
85
00:04:02,800 --> 00:04:05,360
大部分现在最常用的一种方式
86
00:04:05,360 --> 00:04:07,040
就是操作符重载
87
00:04:07,080 --> 00:04:08,920
利用语言的高级特性
88
00:04:09,240 --> 00:04:11,600
既然利用到语言的高级特性
89
00:04:11,640 --> 00:04:12,920
语言的多态性
90
00:04:12,920 --> 00:04:13,960
异常处理
91
00:04:14,280 --> 00:04:16,120
try watch error
92
00:04:16,120 --> 00:04:17,240
这些报错的
93
00:04:17,280 --> 00:04:18,920
还有我的调试的手段
94
00:04:18,960 --> 00:04:21,240
还有我的一些IO的处理
95
00:04:21,280 --> 00:04:23,200
还有程序里面的继承
96
00:04:23,400 --> 00:04:25,560
这一些高级的语言特性
97
00:04:25,880 --> 00:04:28,000
同样没办法被
98
00:04:28,640 --> 00:04:30,840
自动微分系统所识别
99
00:04:30,920 --> 00:04:34,520
这个时候就引起了很多高级语言的特性
100
00:04:34,560 --> 00:04:36,080
在我的AI框架里面
101
00:04:36,120 --> 00:04:38,160
没办法去使用的问题
102
00:04:40,000 --> 00:04:42,480
第四点就是需求重写
103
00:04:42,480 --> 00:04:44,480
现在用到Pytorch
104
00:04:44,480 --> 00:04:45,120
Tensorflow
105
00:04:45,120 --> 00:04:45,760
MindSpore
106
00:04:45,760 --> 00:04:46,920
这些AI框架
107
00:04:46,920 --> 00:04:48,240
其实用的更多
108
00:04:48,280 --> 00:04:51,120
是聚焦于CV、NLP通用领域
109
00:04:51,920 --> 00:04:54,480
但是如果我要利用到HPC的
110
00:04:54,480 --> 00:04:55,280
模拟模拟
111
00:04:55,280 --> 00:04:56,440
我还是用这些框架
112
00:04:56,680 --> 00:04:57,360
不一定
113
00:04:57,600 --> 00:04:58,960
不同受众群体
114
00:04:58,960 --> 00:05:01,520
它对应用性的定义是不一样的
115
00:05:01,560 --> 00:05:03,320
例如我做游戏开发的时候
116
00:05:03,320 --> 00:05:05,640
可能用习惯的是utility
117
00:05:05,760 --> 00:05:07,440
还有Halo的系统
118
00:05:07,720 --> 00:05:08,280
这个时候
119
00:05:08,280 --> 00:05:10,280
如果你让我去用AI框架
120
00:05:10,280 --> 00:05:11,560
可编程的方式
121
00:05:11,560 --> 00:05:13,400
去做游戏引擎的开发
122
00:05:13,400 --> 00:05:14,600
去做物理仿真
123
00:05:14,600 --> 00:05:16,120
或者光线追踪
124
00:05:16,440 --> 00:05:18,920
可能用Pytorch就不是很适合了
125
00:05:18,960 --> 00:05:21,120
这个时候就要求去做一个
126
00:05:21,120 --> 00:05:22,240
需求重写
127
00:05:22,280 --> 00:05:24,280
特还有一些气候模拟
128
00:05:24,280 --> 00:05:26,320
具有DSL属性的一些
129
00:05:26,360 --> 00:05:28,600
特殊领域的子系统里面
130
00:05:28,640 --> 00:05:30,920
使用现在的AI框架
131
00:05:30,920 --> 00:05:32,440
就非常不合适了
132
00:05:33,680 --> 00:05:34,840
关于自动微分
133
00:05:34,840 --> 00:05:36,760
第二个比较大的问题
134
00:05:36,760 --> 00:05:38,440
就是性能问题
135
00:05:38,480 --> 00:05:41,000
性能也是除了应用性以外
136
00:05:41,000 --> 00:05:42,800
用户比较关心的
137
00:05:42,840 --> 00:05:45,440
现在在打市场的时候
138
00:05:45,440 --> 00:05:46,280
说实话
139
00:05:46,320 --> 00:05:49,400
应用性实际上真的很难去比你
140
00:05:49,400 --> 00:05:51,560
Pytorch加英伟达
141
00:05:51,600 --> 00:05:53,240
但是做性能
142
00:05:53,240 --> 00:05:55,760
或者国内一些芯片厂商
143
00:05:55,800 --> 00:05:58,440
它最好的发力点就是性能
144
00:05:58,480 --> 00:06:01,360
如何在性能优先的前提下去
145
00:06:01,400 --> 00:06:04,520
保证应用性也能跟得上
146
00:06:04,560 --> 00:06:06,760
这是一个很大的商业挑战
147
00:06:06,760 --> 00:06:08,240
和技术挑战的问题
148
00:06:08,280 --> 00:06:09,920
现在有一条公式
149
00:06:09,920 --> 00:06:13,240
第一条公式是f等于x的三次方
150
00:06:13,280 --> 00:06:14,120
第二条公式
151
00:06:14,280 --> 00:06:16,720
就是对第一条公式进行求导
152
00:06:16,760 --> 00:06:19,840
dx等于3乘以x的平方
153
00:06:19,880 --> 00:06:23,120
现在简单的把这两条公式
154
00:06:23,160 --> 00:06:26,080
变成一个计算机可识别的公式
155
00:06:28,040 --> 00:06:29,800
这个时候第一条公式
156
00:06:29,800 --> 00:06:31,400
我假设有个中间变量
157
00:06:31,400 --> 00:06:33,960
t等于x乘以x再乘以x
158
00:06:34,000 --> 00:06:35,920
你要把t返回出来
159
00:06:35,960 --> 00:06:38,720
这个对应上面的第一条公式
160
00:06:39,000 --> 00:06:39,680
第二条公式
161
00:06:39,920 --> 00:06:41,760
就是对上一个function
162
00:06:41,800 --> 00:06:42,920
进行一个求导的
163
00:06:42,920 --> 00:06:44,040
叫dfun
164
00:06:44,040 --> 00:06:45,800
里面就变成dx等于3
165
00:06:45,840 --> 00:06:47,160
乘以x
166
00:06:47,200 --> 00:06:49,120
然后return dx出来
167
00:06:49,160 --> 00:06:51,640
但实际上这只是程序的
168
00:06:51,640 --> 00:06:52,960
基本的表达
169
00:06:53,000 --> 00:06:54,760
如果要做性能优化
170
00:06:54,760 --> 00:06:56,400
我做一个三次的乘
171
00:06:56,440 --> 00:06:58,200
然后做两次的乘
172
00:06:58,520 --> 00:07:00,480
我每一次都要去计算
173
00:07:00,480 --> 00:07:01,480
X乘以X
174
00:07:01,480 --> 00:07:03,000
也就是X的平方
175
00:07:03,040 --> 00:07:05,240
能不能把X的平方提取出来
176
00:07:05,640 --> 00:07:07,920
想是有个中间变量
177
00:07:07,920 --> 00:07:08,720
等于t
178
00:07:08,720 --> 00:07:10,720
这个就是x的平方
179
00:07:10,960 --> 00:07:12,520
接着我对正向的输出
180
00:07:12,680 --> 00:07:14,240
就等于x乘以t
181
00:07:14,280 --> 00:07:15,640
我对反向的输出
182
00:07:15,800 --> 00:07:17,040
就是3乘以t
183
00:07:17,040 --> 00:07:18,960
这个时候就可以极大的
184
00:07:18,960 --> 00:07:21,400
去减少计算机的运算量
185
00:07:21,440 --> 00:07:23,040
可能单单看这么一条
186
00:07:23,040 --> 00:07:24,680
简单的公式没多少
187
00:07:24,720 --> 00:07:26,880
但是等整个系统搭起来
188
00:07:26,880 --> 00:07:29,000
等整个神经网络搭起来
189
00:07:29,240 --> 00:07:31,120
这种中间变量的计算
190
00:07:31,120 --> 00:07:32,160
会非常的多
191
00:07:32,720 --> 00:07:35,560
就会引起一系列的性能问题
192
00:07:35,840 --> 00:07:37,320
下面来看看
193
00:07:37,320 --> 00:07:39,760
性能损耗的一个具体的例子
194
00:07:39,760 --> 00:07:42,000
特别是产生非常多的
195
00:07:42,040 --> 00:07:44,080
额外的中间变量
196
00:07:44,320 --> 00:07:46,960
这个Vi就是代表我对求导
197
00:07:47,040 --> 00:07:49,960
我对每个中间变量的导数
198
00:07:49,960 --> 00:07:50,680
可以看到
199
00:07:51,000 --> 00:07:52,640
在反向模式里面
200
00:07:52,640 --> 00:07:54,000
进行求导的时候
201
00:07:54,000 --> 00:07:56,800
里面会引生大量的中间变量
202
00:07:56,840 --> 00:07:59,400
我的V4 V3的导数
203
00:07:59,400 --> 00:08:01,480
同样都会用到V5的导数
204
00:08:01,480 --> 00:08:03,520
我的V1 V2可能会用到
205
00:08:03,520 --> 00:08:04,880
我的V4的导数
206
00:08:04,880 --> 00:08:06,840
这个时候大量的中间变量
207
00:08:06,840 --> 00:08:07,960
都要存起来
208
00:08:07,960 --> 00:08:09,000
不能销毁
209
00:08:09,040 --> 00:08:10,200
如果一旦销毁
210
00:08:10,200 --> 00:08:11,920
我就要重新计算了
211
00:08:11,960 --> 00:08:13,680
这个时候中间变量
212
00:08:13,680 --> 00:08:15,760
就会影响性能
213
00:08:15,760 --> 00:08:17,880
到底是要存储更多
214
00:08:17,880 --> 00:08:19,560
还是要计算更多呢
215
00:08:20,320 --> 00:08:23,320
假设现在有一个二阶微分方程
216
00:08:23,360 --> 00:08:25,080
其中x是自变量
217
00:08:25,080 --> 00:08:26,680
y是未知函数
218
00:08:26,680 --> 00:08:28,760
我对y进行二次求导
219
00:08:28,760 --> 00:08:29,440
可以看到
220
00:08:29,760 --> 00:08:33,160
我首先需要求一个dx对x的一阶导
221
00:08:33,200 --> 00:08:35,800
接着求dy对dx的导数
222
00:08:35,840 --> 00:08:38,920
然后再求最终的dy对dy的
223
00:08:38,920 --> 00:08:40,240
一个第二次导
224
00:08:40,280 --> 00:08:41,960
这个时候每一次
225
00:08:41,960 --> 00:08:45,600
我都需要去利用最小的中间变量
226
00:08:45,640 --> 00:08:46,960
然后一次又一次
227
00:08:46,960 --> 00:08:49,000
产生更多的中间变量
228
00:08:49,040 --> 00:08:50,440
当我的系统一大
229
00:08:50,440 --> 00:08:51,960
当我的模型一大
230
00:08:52,000 --> 00:08:54,200
大量的中间变量就引起了
231
00:08:54,720 --> 00:08:57,720
这个时候针对性能优化问题
232
00:08:57,720 --> 00:09:00,560
又衍生了一些新的研究
233
00:09:00,600 --> 00:09:03,840
就是重计算和编译优化问题
234
00:09:03,880 --> 00:09:06,400
下面这个图就非常好的反映了
235
00:09:06,400 --> 00:09:08,320
重计算和编译优化的问题了
236
00:09:08,360 --> 00:09:10,520
左边向右的这个箭头
237
00:09:10,680 --> 00:09:12,720
就代表正向的计算
238
00:09:12,760 --> 00:09:14,280
右边的这个箭头
239
00:09:14,280 --> 00:09:15,840
这个小箭头右边的
240
00:09:15,840 --> 00:09:19,240
就代表反向模式去计算的
241
00:09:19,240 --> 00:09:21,000
中间的白色圆圈
242
00:09:21,480 --> 00:09:22,880
白色的这些圆圈
243
00:09:23,200 --> 00:09:25,720
代表的就是中间变量
244
00:09:25,720 --> 00:09:28,160
可以看到第一种模式
245
00:09:28,360 --> 00:09:31,120
就是我往前做一个前向计算之后
246
00:09:31,160 --> 00:09:32,520
我往后的时候
247
00:09:32,560 --> 00:09:35,640
产生的小白圆圈比较少
248
00:09:35,680 --> 00:09:38,280
所以我每一次都会重新去计算
249
00:09:38,640 --> 00:09:40,800
这些中间变量存少一点
250
00:09:40,840 --> 00:09:43,480
每一次我都重新计算一把