Skip to content

Commit 61e7313

Browse files
committed
번역 개선 및 reST 문서 오류 수정 (#607)
1 parent d7bda44 commit 61e7313

File tree

1 file changed

+59
-61
lines changed

1 file changed

+59
-61
lines changed

intermediate_source/autograd_saved_tensors_hooks_tutorial.py

Lines changed: 59 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,44 @@
11
"""
22
미분자동화(autograd) 저장된 텐서를 위한 Hooks
3-
===========================================
3+
================================================
44
55
"""
66

77

88
######################################################################
9-
# 파이토치는 일반적으로 역전파를 사용하여 기울기를 계산합니다.
10-
# 그러나 특정 작업에서는 역전파를 수행하기 위한 중간결과를 저장해야 합니다.
11-
# 이번 튜토리얼에서는 이러한 텐서를 저장/검색하는 방법과 패킹/언패킹 프로세스를 제어하기위한 hooks을 정하는 방법을 안내합니다.
9+
# 파이토치는 일반적으로 역전파를 사용하여 기울기를 계산합니다.
10+
# 그러나 특정 작업에서는 역전파를 수행하기 위한 중간결과를 저장해야 합니다.
11+
# 이번 튜토리얼에서는 이러한 텐서를 저장/검색하는 방법과 패킹/언패킹 프로세스를 제어하기위한 hooks을 정하는 방법을 안내합니다.
1212

1313
# 이 튜토리얼에서는 사용자가 역전파가 이론상에서 작동하는 방식에 익숙하다고 가정합니다. 아니라면, 아래의 자료를 먼저 읽어보세요.
1414
# https://colab.research.google.com/drive/1aWNdmYt7RcHMbUk-Xz2Cv5-cGFSWPXe0#scrollTo=AHcEJ6nXUb7W
1515

1616
######################################################################
1717
# 저장된 tensor
18-
# -------------
18+
# -------------------
1919

2020

2121
######################################################################
22-
# 모델의 훈련은 일반적으로 모델을 인퍼런스하는 것보다 학습하는 과정에서 메모리를 더 많이 사용합니다.
23-
# 대략적으로 말하면 파이토치는 역전파를 호출하는데 필요한 계산 그래프를 저장해야하므로 추가 메모리 사용량이 있기 때문입니다.
22+
# 모델의 훈련은 일반적으로 모델을 인퍼런스하는 것보다 학습하는 과정에서 메모리를 더 많이 사용합니다.
23+
# 대략적으로 말하면 파이토치는 역전파를 호출하는데 필요한 계산 그래프를 저장해야하므로 추가 메모리 사용량이 있기 때문입니다.
2424
# 이 튜토리얼의 한가지 목표는 이러한 이해에 대한 미세 조정을 실행하는 것입니다.
2525
#
2626
# 사실, 이 그래프 자체로는 가끔은 그다지 많은 메모리를 사용하진 않습니다. 여타의 텐서들을 복제하지 않는 것 처럼요.
27-
# 그러나, 그래프는 *참조* 를 유지할 수 있습니다.
28-
# 그렇지 않으면 범위를 벗어난 텐서를 : **저장된 텐서** 라고 명명할 수 있습니다.
27+
# 그러나, 그래프는 *참조* 를 유지할 수 있습니다.
28+
# 그렇지 않으면 범위를 벗어난 텐서를 : **저장된 텐서** 라고 명명할 수 있습니다.
2929

3030

3131
######################################################################
32-
# (일반적으로)모델을 훈련하는데 평가보다 더 많은 메모리를 소하게 되는 이유는 무엇일까요?
33-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32+
# (일반적으로) 모델을 훈련하는데 평가보다 더 많은 메모리를 사용하는 이유는 무엇일까요?
33+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3434

3535

3636
######################################################################
3737
# 간단한 예제를 시작해봅시다: :math: `y = a \mapsto \cdot b` , 이것은 미분량(그래디언트)로 알고있는 :math: `y`,로 각각 :math: `a` and
38-
# :math: `b`:로 상정합니다.
39-
38+
# :math: `b`:로 상정합니다.
4039

41-
.. math:: \frac{\partial y}{\partial a} = b
42-
.. math:: \frac{\partial y}{\partial b} = a
40+
# .. math:: \frac{\partial y}{\partial a} = b
41+
# .. math:: \frac{\partial y}{\partial b} = a
4342

4443

4544
import torch
@@ -49,18 +48,18 @@
4948
y = a * b
5049

5150
#################################################################
52-
# torchviz를 사용해서, 계산그래프를 시각화 할 수 있습니다.
53-
.. figure:: https://user-images.githubusercontent.com/8019486/130124513-72e016a3-c36f-42b9-88e2-53baf3e016c5.png
54-
:width: 300
55-
:align: center
51+
# torchviz를 사용해서, 계산그래프를 시각화 할 수 있습니다.
52+
# .. figure:: https://user-images.githubusercontent.com/8019486/130124513-72e016a3-c36f-42b9-88e2-53baf3e016c5.png
53+
# :width: 300
54+
# :align: center
5655

5756

5857
######################################################################
5958
# 이 예제에서 파이토치는 중간 값 :math: `a` 및 :math: `b` 를 저장하여 역방향 동안 기울기를 계산합니다.
6059
#
61-
.. figure:: https://user-images.githubusercontent.com/8019486/130124538-3da50977-6f0b-46d0-8909-5456ade9b598.png
62-
:width: 300
63-
:align: center
60+
# .. figure:: https://user-images.githubusercontent.com/8019486/130124538-3da50977-6f0b-46d0-8909-5456ade9b598.png
61+
# :width: 300
62+
# :align: center
6463

6564

6665
######################################################################
@@ -71,7 +70,7 @@
7170

7271

7372
######################################################################
74-
# 계산 그래프가 깊어질수록 *저장된 텐서*가 더 많이 저장됩니다. 한편, 텐서는 그래프가 아니었다면 범위를 벗어나게 됩니다.
73+
# 계산 그래프가 깊어질수록 *저장된 텐서*가 더 많이 저장됩니다. 한편, 텐서는 그래프가 아니었다면 범위를 벗어나게 됩니다.
7574

7675
def f(x):
7776
return x * x
@@ -80,14 +79,14 @@ def f(x):
8079
y = f(f(f(x)))
8180

8281
######################################################################
83-
.. figure :: https://user-images.githubusercontent.com/8019486/130124570-f1074098-1bb3-459e-bf5a-03bf6f65b403.png
84-
:width: 500
85-
:align: center
82+
#.. figure :: https://user-images.githubusercontent.com/8019486/130124570-f1074098-1bb3-459e-bf5a-03bf6f65b403.png
83+
# :width: 500
84+
# :align: center
8685

8786
######################################################################
8887
# 위의 예제에서 미분(grad)없이 실행하면 범위내의 ``x`` 와 ``y`` 는 유지되지만
8988
# 그래프에서는 ``f(x)``와 ``f(f(x)`가 추가로 저장됩니다.
90-
# 따라서 훈련 중 정방향 경로를 실행하면 평가중에 (더 정확하게는 자동미분(auto grad)가 필요하지 않은 경우보다) 메모리 사용비중이 더 많아지게 됩니다.
89+
# 따라서 훈련 중 정방향 경로를 실행하면 평가중에 (더 정확하게는 자동미분(auto grad)가 필요하지 않은 경우보다) 메모리 사용비중이 더 많아지게 됩니다.
9190

9291

9392
######################################################################
@@ -108,7 +107,7 @@ def f(x):
108107

109108

110109
######################################################################
111-
# 그러나 이것은 항상 같은 결과를 보여주지 않습니다.
110+
# 그러나 이것은 항상 같은 결과를 보여주지 않습니다.
112111

113112
a = torch.randn(5, requires_grad=True)
114113
y = torch.exp(a)
@@ -119,7 +118,7 @@ def f(x):
119118
######################################################################
120119
# 내부적으로는 파이토치는 참조주기를 방지하기 위해서 텐서 ``y``를 **패킹** 및 **언패킹** 했습니다
121120
# 경험상, 역전파 저장된 텐서에 엑세스하면 원래 텐서와 동일한 텐서의 객체가 생성된다는 결과를 기대해서는 *안됩니다.*
122-
# 그러나 동일한 *저장소*를 공유합니다.
121+
# 그러나 동일한 *저장소*를 공유합니다.
123122

124123
######################################################################
125124
# 저장된 텐서 hooks
@@ -147,10 +146,10 @@ def unpack_hook(x):
147146

148147

149148
######################################################################
150-
# ``pack_hook`` 함수는 작업이 역전파를 위해 텐서를 저장할 때 마다 호출됩니다. 그러면
149+
# ``pack_hook`` 함수는 작업이 역전파를 위해 텐서를 저장할 때 마다 호출됩니다. 그러면
151150
# ``pack_hook``의 출력이 원래 텐서 대신 계산 그래프에 저장됩니다.
152-
# ``unpack_hook``은 해당 반환 값을 사용하여 역방향 전달 중에 실제로 사용된 텐서를 새 텐서로 계산합니다.
153-
# 일반적으로 ``unpack_hook(pack_hook(t))`` 가 ``t`` 와 같길 기대합니다.
151+
# ``unpack_hook``은 해당 반환 값을 사용하여 역방향 전달 중에 실제로 사용된 텐서를 새 텐서로 계산합니다.
152+
# 일반적으로 ``unpack_hook(pack_hook(t))`` 가 ``t`` 와 같길 기대합니다.
154153

155154

156155
x = torch.randn(5, requires_grad=True)
@@ -161,22 +160,22 @@ def unpack_hook(x):
161160

162161

163162
######################################################################
164-
# 한 가지 주의할 점은 ``unpack_hook``이 올바른 값을 가진 텐서를 파생할 수 있는 한
165-
# ``pack_hook``의 출력은 *모든 파이썬 객체*가 될 수 있다는 것입니다.
163+
# 한 가지 주의할 점은 ``unpack_hook``이 올바른 값을 가진 텐서를 파생할 수 있는 한
164+
# ``pack_hook``의 출력은 *모든 파이썬 객체*가 될 수 있다는 것입니다.
166165

167166
######################################################################
168167
# 몇 가지 특이한 예제들
169-
# ~~~~~~~~~~~~~~~~~~~~
168+
# ~~~~~~~~~~~~~~~~~~~~~~~~
170169

171170

172171

173172
######################################################################
174-
# 먼저, 가능성을 설명하기 위해서 몇 가지 어리석어보이는 예가 있지만 아마 하고싶지 않을 수도 있습니다.
173+
# 먼저, 가능성을 설명하기 위해서 몇 가지 어리석어보이는 예가 있지만 아마 하고싶지 않을 수도 있습니다.
175174

176175
######################################################################
177176
# **반환 및 int**
178177
#
179-
# 파이썬 리스트의 인덱스반환
178+
# 파이썬 리스트의 인덱스반환
180179
#
181180
# 상대적으로는 상관없지만 논란의 여지가 있는 유용성
182181

@@ -199,7 +198,7 @@ def unpack(x):
199198
######################################################################
200199
# **튜플의 반환**
201200
#
202-
# 일부 텐서와 함수를 반환하고 압축을 푸는 방법은 현재 형태로는 유용하지 않을 것입니다.
201+
# 일부 텐서와 함수를 반환하고 압축을 푸는 방법은 현재 형태로는 유용하지 않을 것입니다.
203202

204203
def pack(x):
205204
delta = torch.randn(*x.size())
@@ -231,22 +230,22 @@ def unpack(packed):
231230

232231

233232
######################################################################
234-
# 이러한 예제는 실제로 유용하지 않을 것이지만 ``pack_hook``의 출력이 원래 텐서의 내용을 검색하기에 충분한 정보를 포함하는 한
235-
# 실제로 모든 Python의 객체가 될 수 있음을 보여줍니다.
236-
# 다음 섹션에서는 더 유용한 응용프로그램에 중점을 두겠습니다.
233+
# 이러한 예제는 실제로 유용하지 않을 것이지만 ``pack_hook``의 출력이 원래 텐서의 내용을 검색하기에 충분한 정보를 포함하는 한
234+
# 실제로 모든 Python의 객체가 될 수 있음을 보여줍니다.
235+
# 다음 섹션에서는 더 유용한 응용프로그램에 중점을 두겠습니다.
237236

238237
######################################################################
239238
# 텐서를 CPU에 저장하기
240-
# ~~~~~~~~~~~~~~~~~~~~
239+
# ~~~~~~~~~~~~~~~~~~~~~~~~
241240

242241

243242

244243
######################################################################
245-
# 매우 빈번하게, 계산 그래프를 수반하는 텐서는 GPU에 있습니다.
246-
# 그래프에 이러한 텐서에 대한 참조를 유지하는 것은 대부분의 모델이 평가중에 정상적으로 수행되었을 때
247-
# 훈련중에 GPU 메모리가 부족하게 만드는 원인이 됩니다.
244+
# 매우 빈번하게, 계산 그래프를 수반하는 텐서는 GPU에 있습니다.
245+
# 그래프에 이러한 텐서에 대한 참조를 유지하는 것은 대부분의 모델이 평가중에 정상적으로 수행되었을 때
246+
# 훈련중에 GPU 메모리가 부족하게 만드는 원인이 됩니다.
248247
#
249-
# hooks는 이를 구현하는 매우 간단한 방법을 제공합니다.
248+
# hooks는 이를 구현하는 매우 간단한 방법을 제공합니다.
250249

251250

252251

@@ -292,8 +291,8 @@ def forward(self, x):
292291
#
293292
# 물론 네트워크 특정부분만 CPU에 저장하여 절충안을 조정할 수 있습니다.
294293
#
295-
# 예를 들어, 모든 모듈을 감싸두고 해당 텐서를 CPU에 저장하는 특별한
296-
# ``nn.Module`` 을 정의할 수 있습니다.
294+
# 예를 들어, 모든 모듈을 감싸두고 해당 텐서를 CPU에 저장하는 특별한
295+
# ``nn.Module`` 을 정의할 수 있습니다.
297296

298297
class SaveToCpu(nn.Module):
299298
def __init__(self, module):
@@ -317,12 +316,12 @@ def forward(self, *args, **kwargs):
317316

318317
######################################################################
319318
# 텐서를 디스크에 저장하기
320-
# ~~~~~~~~~~~~~~~~~~~~~~
319+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
321320

322321

323322

324323
######################################################################
325-
# 마찬가지로, 이러한 텐서를 디스크에 저장하고 싶을 수 도 있습니다. 다시 말하지만 이것은 앞서말한 hooks로 달성할 수 있습니다.
324+
# 마찬가지로, 이러한 텐서를 디스크에 저장하고 싶을 수 도 있습니다. 다시 말하지만 이것은 앞서말한 hooks로 달성할 수 있습니다.
326325

327326
######################################################################
328327
# 단순한 버전의 아마 이럴것입니다.
@@ -342,8 +341,8 @@ def unpack_hook(name):
342341

343342

344343
######################################################################
345-
# 위의 코드가 나쁜 이유는 디스크에 저장된 파일이 누출되고 해당 파일을 지울수도 없기 때문입니다.
346-
# 이 문제를 해결하는 것은 그렇게 간단하지 않아 보입니다.
344+
# 위의 코드가 나쁜 이유는 디스크에 저장된 파일이 누출되고 해당 파일을 지울수도 없기 때문입니다.
345+
# 이 문제를 해결하는 것은 그렇게 간단하지 않아 보입니다.
347346
#
348347
# 잘못된 버전 - 힌트: 이렇게 하지 마시오.
349348

@@ -365,9 +364,9 @@ def unpack_hook(name):
365364

366365

367366
######################################################################
368-
# 위의 코드가 작동하지 않는 이유는 ``unpack_hook``가 여러번 호출되기 때문입니다.
367+
# 위의 코드가 작동하지 않는 이유는 ``unpack_hook`` 가 여러번 호출되기 때문입니다.
369368
# 먼저 압축을 풀 때 파일을 삭제하면 처음에, 저장된 텐서에 엑세스시에 사용할 수 없습니다.
370-
# 두 번째에는 오류가 발생합니다.
369+
# 두 번째에는 오류가 발생합니다.
371370

372371
x = torch.ones(5, requires_grad=True)
373372
with torch.autograd.graph.saved_tensors_hooks(pack_hook, unpack_hook):
@@ -382,7 +381,7 @@ def unpack_hook(name):
382381

383382
######################################################################
384383
# 이문제를 해결하기위해 이점을 활용하는 hooks의 버전을 작성할 수 있습니다.
385-
# 파이토치가 저장된 데이터를 자동으로 해제(삭제)한다는 사실이 더이상 필요하지 않을 때입니다.
384+
# 파이토치가 저장된 데이터를 자동으로 해제(삭제)한다는 사실이 더이상 필요하지 않을 때입니다.
386385

387386
class SelfDeletingTempFile():
388387
def __init__(self):
@@ -402,12 +401,10 @@ def unpack_hook(temp_file):
402401

403402
######################################################################
404403
# ``backward`` 를 호출하면 ``pack_hook`` 이 삭제되고,
405-
# 파일이 제거되도록 하므로 더 이상 파일이 누출되지 않습니다.
404+
# 파일이 제거되도록 하므로 더 이상 파일이 누출되지 않습니다.
406405
#
407406
# 다음과 같은 방식으로 모델에 사용할 수 있습니다.
408407

409-
410-
# Only save on disk tensors that have size >= 1000
411408
# 사이즈 >=1000인 텐서만이 디스크에 저장될 수 있습니다.
412409

413410
SAVE_ON_DISK_THRESHOLD = 1000
@@ -437,9 +434,10 @@ def forward(self, *args, **kwargs):
437434

438435

439436
######################################################################
440-
# 이 마지막 예에서는
441-
# 반드시 저장해야하며 이 기능을 ``nn.DataParallel`` 와 어떻게 조합하는 텐서들에 대해 어떻게 필터하는지에 대한 증명을 해보았습니다.
437+
# 이 마지막 예제에서는 저장해야 하는 (여기에서는 원소의 수가 1000 이상인) 텐서들을 골라내는 방법과
438+
# 이 기능을 ``nn.DataParallel`` 과 함께 사용하는 방법을 살펴보았습니다.
442439

443440

444441
######################################################################
445-
# 만일 여기까지 따라오셨다면, 축하합니다! 당신은 저장된 텐서 hooks을 어떻게 사용하는지 그리고 계산 메모리의 절충안에서 몇 가지 시나리오를 유용하게 사용할 수 있습니다!
442+
# 여기까지 잘 따라오셨나요? 축하합니다!
443+
# 이제 저장된 텐서 hooks을 어떻게 사용하는지와 연산 시 메모리 관리(trade-offs)에 유용하게 사용할 수 있는 방법을 알게 되셨습니다.

0 commit comments

Comments
 (0)