From a1f4057fd27d5ff0288412a2c5df7e9cb4ecd9b5 Mon Sep 17 00:00:00 2001 From: BcKmini Date: Sat, 11 Oct 2025 22:57:34 +0900 Subject: [PATCH 1/9] translation/intermediate_source_forward_ad_usage --- intermediate_source/forward_ad_usage.py | 193 +++++++++++------------- 1 file changed, 87 insertions(+), 106 deletions(-) diff --git a/intermediate_source/forward_ad_usage.py b/intermediate_source/forward_ad_usage.py index 10965d64a..ffd66a707 100644 --- a/intermediate_source/forward_ad_usage.py +++ b/intermediate_source/forward_ad_usage.py @@ -1,32 +1,21 @@ # -*- coding: utf-8 -*- """ -Forward-mode Automatic Differentiation (Beta) +순전파 모드 자동 미분(Beta) ============================================= -This tutorial demonstrates how to use forward-mode AD to compute -directional derivatives (or equivalently, Jacobian-vector products). +**번역**: `김경민 `_ -The tutorial below uses some APIs only available in versions >= 1.11 -(or nightly builds). +이 튜토리얼은 순전파 모드 자동 미분(Forward-mode AD)을 사용하여 방향성 도함수(directional derivative) 또는 야코비안-벡터 곱(Jacobian-vector product)을 계산하는 방법을 보여줍니다. -Also note that forward-mode AD is currently in beta. The API is -subject to change and operator coverage is still incomplete. +아래 튜토리얼은 1.11 이상 버전(또는 나이틀리 빌드)에서만 사용할 수 있는 일부 API를 사용합니다. -Basic Usage +또한, 순전파 모드 AD는 현재 베타 버전입니다. 따라서 API가 변경될 수 있으며, 아직 일부 연산자는 지원되지 않을 수 있습니다. + +기본 사용법 -------------------------------------------------------------------- -Unlike reverse-mode AD, forward-mode AD computes gradients eagerly -alongside the forward pass. We can use forward-mode AD to compute a -directional derivative by performing the forward pass as before, -except we first associate our input with another tensor representing -the direction of the directional derivative (or equivalently, the ``v`` -in a Jacobian-vector product). When an input, which we call "primal", is -associated with a "direction" tensor, which we call "tangent", the -resultant new tensor object is called a "dual tensor" for its connection -to dual numbers[0]. - -As the forward pass is performed, if any input tensors are dual tensors, -extra computation is performed to propagate this "sensitivity" of the -function. +역전파 모드 자동 미분(Reverse-mode AD)과 달리, 순전파 모드 AD는 순전파(forward pass)를 진행하며 기울기(gradient)를 즉시(계산을 미루지 않고) 계산합니다. 순전파 모드 AD로 방향성 도함수를 계산하려면, 먼저 입력을 방향성 도함수의 방향을 나타내는 다른 텐서(야코비안-벡터 곱의 `v`에 해당)와 연결한 뒤 이전과 같이 순전파를 수행하면 됩니다. '원시(primal)'라고 부르는 입력이 '탄젠트(tangent)'라고 부르는 '방향' 텐서와 연결될 때, 결과로 나오는 새로운 텐서 객체는 이중수(dual numbers) [0] 와의 관련성 때문에 '이중 텐서(dual tensor)'라고 불립니다. + +순전파가 수행될 때, 입력 텐서 중 하나라도 이중 텐서이면 함수의 '민감도(sensitivity)'를 전파하기 위해 추가적인 연산이 수행됩니다. """ @@ -39,49 +28,45 @@ def fn(x, y): return x ** 2 + y ** 2 -# All forward AD computation must be performed in the context of -# a ``dual_level`` context. All dual tensors created in such a context -# will have their tangents destroyed upon exit. This is to ensure that -# if the output or intermediate results of this computation are reused -# in a future forward AD computation, their tangents (which are associated -# with this computation) won't be confused with tangents from the later -# computation. +# 모든 순전파 AD 연산은 ``dual_level`` 컨텍스트 안에서 수행해야 합니다. +# 이 컨텍스트에서 생성된 모든 이중 텐서의 탄젠트는 컨텍스트를 벗어날 때 소멸됩니다. +# 이는 해당 연산의 출력이나 중간 결과가 향후 다른 순전파 AD 연산에 재사용될 때, +# 현재 연산에 속한 탄젠트가 나중 연산의 탄젠트와 혼동되는 것을 방지하기 위함입니다. with fwAD.dual_level(): - # To create a dual tensor we associate a tensor, which we call the - # primal with another tensor of the same size, which we call the tangent. - # If the layout of the tangent is different from that of the primal, - # The values of the tangent are copied into a new tensor with the same - # metadata as the primal. Otherwise, the tangent itself is used as-is. + # 이중 텐서를 만들려면 '원시(primal)' 텐서를 같은 크기의 다른 텐서, + # 즉 '탄젠트(tangent)'와 연결합니다. + # 만약 탄젠트의 레이아웃이 원시의 레이아웃과 다르면, + # 탄젠트의 값은 원시와 동일한 메타데이터를 갖는 새 텐서에 복사됩니다. + # 그렇지 않으면 탄젠트 자체가 그대로 사용됩니다. # - # It is also important to note that the dual tensor created by - # ``make_dual`` is a view of the primal. + # ``make_dual`` 로 생성된 이중 텐서는 원시 텐서의 **뷰(데이터를 공유하는 참조)** 라는 점도 + # 중요합니다. dual_input = fwAD.make_dual(primal, tangent) assert fwAD.unpack_dual(dual_input).tangent is tangent - # To demonstrate the case where the copy of the tangent happens, - # we pass in a tangent with a layout different from that of the primal + # 탄젠트가 복사되는 경우를 보여주기 위해, + # 원시와 다른 레이아웃을 가진 탄젠트를 전달합니다. dual_input_alt = fwAD.make_dual(primal, tangent.T) assert fwAD.unpack_dual(dual_input_alt).tangent is not tangent - # Tensors that do not have an associated tangent are automatically - # considered to have a zero-filled tangent of the same shape. + # 탄젠트가 연결되지 않은 텐서는 자동으로 + # 같은 shape을 가지며 0으로 채워진 탄젠트를 가진 것으로 간주됩니다. plain_tensor = torch.randn(10, 10) dual_output = fn(dual_input, plain_tensor) - # Unpacking the dual returns a ``namedtuple`` with ``primal`` and ``tangent`` - # as attributes + # 이중 텐서를 풀면(unpack) ``primal`` 과 ``tangent`` 를 + # 속성으로 갖는 ``namedtuple`` 이 반환됩니다. jvp = fwAD.unpack_dual(dual_output).tangent assert fwAD.unpack_dual(dual_output).tangent is None ###################################################################### -# Usage with Modules +# 모듈과 함께 사용하기 # -------------------------------------------------------------------- -# To use ``nn.Module`` with forward AD, replace the parameters of your -# model with dual tensors before performing the forward pass. At the -# time of writing, it is not possible to create dual tensor -# `nn.Parameter`s. As a workaround, one must register the dual tensor -# as a non-parameter attribute of the module. +# ``nn.Module`` 을 순전파 AD와 함께 사용하려면, 순전파를 수행하기 전에 +# 모델의 매개변수(parameter)를 이중 텐서로 교체해야 합니다. 현재 이중 텐서로 된 +# `nn.Parameter` 는 생성할 수 없습니다. 이에 대한 해결 방법으로, +# 이중 텐서를 모듈의 매개변수가 아닌 일반 속성으로 등록해야 합니다. import torch.nn as nn @@ -100,52 +85,52 @@ def fn(x, y): jvp = fwAD.unpack_dual(out).tangent ###################################################################### -# Using the functional Module API (beta) +# 함수형 모듈 API 사용하기 (Beta) # -------------------------------------------------------------------- -# Another way to use ``nn.Module`` with forward AD is to utilize -# the functional Module API (also known as the stateless Module API). +# ``nn.Module`` 을 순전파 AD와 함께 사용하는 또 다른 방법은 +# 함수형 모듈 API를 활용하는 것입니다. from torch.func import functional_call -# We need a fresh module because the functional call requires the -# the model to have parameters registered. +# functional_call은 모델에 매개변수가 등록되어 있어야 하므로 +# 새로운 모듈이 필요합니다. model = nn.Linear(5, 5) dual_params = {} with fwAD.dual_level(): for name, p in params.items(): - # Using the same ``tangents`` from the above section + # 위 섹션과 동일한 ``tangents`` 를 사용합니다. dual_params[name] = fwAD.make_dual(p, tangents[name]) out = functional_call(model, dual_params, input) jvp2 = fwAD.unpack_dual(out).tangent -# Check our results +# 결과 확인 assert torch.allclose(jvp, jvp2) ###################################################################### -# Custom autograd Function +# 사용자 정의 autograd Function # -------------------------------------------------------------------- -# Custom Functions also support forward-mode AD. To create custom Function -# supporting forward-mode AD, register the ``jvp()`` static method. It is -# possible, but not mandatory for custom Functions to support both forward -# and backward AD. See the -# `documentation `_ -# for more information. +# 사용자 정의 Function 또한 순전파 모드 AD를 지원합니다. 순전파 모드 AD를 +# 지원하는 사용자 정의 Function을 만들려면 ``jvp()`` 정적 메소드를 +# 등록해야 합니다. 사용자 정의 Function이 순전파와 역전파 AD를 모두 지원하는 것도 +# 가능하지만 필수는 아닙니다. 더 자세한 정보는 +# `문서 `_ +# 를 참고하세요. class Fn(torch.autograd.Function): @staticmethod def forward(ctx, foo): result = torch.exp(foo) - # Tensors stored in ``ctx`` can be used in the subsequent forward grad - # computation. + # ``ctx`` 에 저장된 텐서는 이후의 순전파 기울기 + # 계산에 사용할 수 있습니다. ctx.result = result return result @staticmethod def jvp(ctx, gI): gO = gI * ctx.result - # If the tensor stored in`` ctx`` will not also be used in the backward pass, - # one can manually free it using ``del`` + # ``ctx`` 에 저장된 텐서가 역전파에 사용되지 않을 경우, + # ``del`` 을 사용하여 수동으로 메모리에서 해제할 수 있습니다. del ctx.result return gO @@ -159,33 +144,30 @@ def jvp(ctx, gI): dual_output = fn(dual_input) jvp = fwAD.unpack_dual(dual_output).tangent -# It is important to use ``autograd.gradcheck`` to verify that your -# custom autograd Function computes the gradients correctly. By default, -# ``gradcheck`` only checks the backward-mode (reverse-mode) AD gradients. Specify -# ``check_forward_ad=True`` to also check forward grads. If you did not -# implement the backward formula for your function, you can also tell ``gradcheck`` -# to skip the tests that require backward-mode AD by specifying -# ``check_backward_ad=False``, ``check_undefined_grad=False``, and -# ``check_batched_grad=False``. +# 사용자 정의 autograd Function이 기울기를 올바르게 계산하는지 확인하려면 +# ``autograd.gradcheck`` 를 사용하는 것이 중요합니다. 기본적으로 +# ``gradcheck`` 는 역전파 모드(reverse-mode) AD 기울기만 확인합니다. +# ``check_forward_ad=True`` 를 지정하여 순전파 기울기도 확인하도록 할 수 있습니다. +# 만약 Function에 대한 역전파를 구현하지 않았다면, ``check_backward_ad=False``, +# ``check_undefined_grad=False``, ``check_batched_grad=False`` 를 지정하여 +# ``gradcheck`` 가 역전파 모드 AD가 필요한 테스트를 건너뛰도록 할 수 있습니다. torch.autograd.gradcheck(Fn.apply, (primal,), check_forward_ad=True, check_backward_ad=False, check_undefined_grad=False, check_batched_grad=False) ###################################################################### -# Functional API (beta) +# 함수형 API (Beta) # -------------------------------------------------------------------- -# We also offer a higher-level functional API in functorch -# for computing Jacobian-vector products that you may find simpler to use -# depending on your use case. +# Functorch는 야코비안-벡터 곱을 계산하기 위한 고수준 함수형 API도 +# 제공하며, 사용 사례에 따라 더 간단하게 사용할 수 있습니다. # -# The benefit of the functional API is that there isn't a need to understand -# or use the lower-level dual tensor API and that you can compose it with -# other `functorch transforms (like vmap) `_; -# the downside is that it offers you less control. +# 함수형 API의 장점은 저수준의 이중 텐서 API를 이해하거나 사용할 +# 필요가 없으며, 다른 `functorch 변환(vmap 등)과 결합 `_ +# 할 수 있다는 것입니다. 단점은 세밀한 제어가 어렵다는 점입니다. # -# Note that the remainder of this tutorial will require functorch -# (https://github.com/pytorch/functorch) to run. Please find installation -# instructions at the specified link. +# 이 튜토리얼의 나머지 부분을 실행하려면 functorch +# (https://github.com/pytorch/functorch) 가 필요합니다. +# 설치 방법은 해당 링크에서 확인해주세요. import functorch as ft @@ -197,14 +179,15 @@ def jvp(ctx, gI): def fn(x, y): return x ** 2 + y ** 2 -# Here is a basic example to compute the JVP of the above function. -# The ``jvp(func, primals, tangents)`` returns ``func(*primals)`` as well as the -# computed Jacobian-vector product (JVP). Each primal must be associated with a tangent of the same shape. -primal_out, tangent_out = ft.jvp(fn, (primal0, primal1), (tangent0, tangent1)) +# 위 함수의 JVP를 계산하는 기본 예제입니다. +# ``jvp(func, primals, tangents)`` 는 ``func(*primals)`` 의 결과와 계산된 +# 야코비안-벡터 곱(JVP)을 함께 반환합니다. 각 원시는 같은 shape의 탄젠트와 +# 연결되어야 합니다. +primal_out, tangent_out = ft.jvp(fn, (primal0, primal1), (tan_gent0, tangent1)) -# ``functorch.jvp`` requires every primal to be associated with a tangent. -# If we only want to associate certain inputs to `fn` with tangents, -# then we'll need to create a new function that captures inputs without tangents: +# ``functorch.jvp`` 는 모든 원시가 탄젠트와 연결될 것을 요구합니다. +# 만약 ``fn`` 의 특정 입력에만 탄젠트를 연결하고 싶다면, +# 탄젠트가 없는 입력을 받는 새로운 함수를 만들어야 합니다. primal = torch.randn(10, 10) tangent = torch.randn(10, 10) y = torch.randn(10, 10) @@ -214,28 +197,26 @@ def fn(x, y): primal_out, tangent_out = ft.jvp(new_fn, (primal,), (tangent,)) ###################################################################### -# Using the functional API with Modules +# 함수형 API를 모듈과 함께 사용하기 # -------------------------------------------------------------------- -# To use ``nn.Module`` with ``functorch.jvp`` to compute Jacobian-vector products -# with respect to the model parameters, we need to reformulate the -# ``nn.Module`` as a function that accepts both the model parameters and inputs -# to the module. +# ``nn.Module`` 과 ``functorch.jvp`` 를 함께 사용하여 모델 매개변수에 대한 +# 야코비안-벡터 곱을 계산하려면, ``nn.Module`` 을 모델 매개변수와 +# 모듈의 입력을 모두 인자로 받는 함수로 재구성해야 합니다. model = nn.Linear(5, 5) input = torch.randn(16, 5) tangents = tuple([torch.rand_like(p) for p in model.parameters()]) -# Given a ``torch.nn.Module``, ``ft.make_functional_with_buffers`` extracts the state -# (``params`` and buffers) and returns a functional version of the model that -# can be invoked like a function. -# That is, the returned ``func`` can be invoked like -# ``func(params, buffers, input)``. -# ``ft.make_functional_with_buffers`` is analogous to the ``nn.Modules`` stateless API -# that you saw previously and we're working on consolidating the two. +# ``ft.make_functional_with_buffers`` 는 주어진 ``torch.nn.Module`` 에서 +# 상태(``params`` 와 버퍼)를 추출하고, 함수처럼 호출할 수 있는 +# 함수형 버전의 모델을 반환합니다. +# 즉, 반환된 ``func`` 는 ``func(params, buffers, input)`` 처럼 호출할 수 있습니다. +# ``ft.make_functional_with_buffers`` 는 이전에 보았던 ``nn.Module`` 의 상태 없는 API와 +# 유사하며, 이 둘을 통합하는 작업이 진행 중입니다. func, params, buffers = ft.make_functional_with_buffers(model) -# Because ``jvp`` requires every input to be associated with a tangent, we need to -# create a new function that, when given the parameters, produces the output +# ``jvp`` 는 모든 입력이 탄젠트와 연결될 것을 요구하므로, +# 매개변수를 받았을 때 출력을 생성하는 새로운 함수를 만들어야 합니다. def func_params_only(params): return func(params, buffers, input) @@ -243,4 +224,4 @@ def func_params_only(params): ###################################################################### -# [0] https://en.wikipedia.org/wiki/Dual_number +# [0] https://en.wikipedia.org/wiki/Dual_number \ No newline at end of file From 37da9ab4021f2a141bfdd39875c4df5492a7def7 Mon Sep 17 00:00:00 2001 From: BcKmini Date: Sat, 11 Oct 2025 23:10:26 +0900 Subject: [PATCH 2/9] translation/intermediate_source_forward_ad_usage --- intermediate_source/forward_ad_usage.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/intermediate_source/forward_ad_usage.py b/intermediate_source/forward_ad_usage.py index ffd66a707..b4085a56f 100644 --- a/intermediate_source/forward_ad_usage.py +++ b/intermediate_source/forward_ad_usage.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- """ -순전파 모드 자동 미분(Beta) +순전파 모드 자동 미분 (Beta) ============================================= - **번역**: `김경민 `_ 이 튜토리얼은 순전파 모드 자동 미분(Forward-mode AD)을 사용하여 방향성 도함수(directional derivative) 또는 야코비안-벡터 곱(Jacobian-vector product)을 계산하는 방법을 보여줍니다. @@ -13,9 +12,9 @@ 기본 사용법 -------------------------------------------------------------------- -역전파 모드 자동 미분(Reverse-mode AD)과 달리, 순전파 모드 AD는 순전파(forward pass)를 진행하며 기울기(gradient)를 즉시(계산을 미루지 않고) 계산합니다. 순전파 모드 AD로 방향성 도함수를 계산하려면, 먼저 입력을 방향성 도함수의 방향을 나타내는 다른 텐서(야코비안-벡터 곱의 `v`에 해당)와 연결한 뒤 이전과 같이 순전파를 수행하면 됩니다. '원시(primal)'라고 부르는 입력이 '탄젠트(tangent)'라고 부르는 '방향' 텐서와 연결될 때, 결과로 나오는 새로운 텐서 객체는 이중수(dual numbers) [0] 와의 관련성 때문에 '이중 텐서(dual tensor)'라고 불립니다. +역전파 모드 자동 미분(Reverse-mode AD)과 달리, 순전파 모드 AD는 순전파를 진행하며 기울기를 즉시 계산합니다. 순전파 모드 AD로 방향성 도함수를 계산하려면, 먼저 입력을 방향성 도함수의 방향을 나타내는 다른 텐서(야코비안-벡터 곱의 `v`에 해당)와 연결한 뒤 이전과 같이 순전파를 수행하면 됩니다. '원시(primal)'라고 부르는 입력이 '탄젠트(tangent)'라고 부르는 '방향' 텐서와 연결될 때, 결과로 나오는 새로운 텐서 객체는 이중수 [0] 와의 관련성 때문에 '이중 텐서'라고 불립니다. -순전파가 수행될 때, 입력 텐서 중 하나라도 이중 텐서이면 함수의 '민감도(sensitivity)'를 전파하기 위해 추가적인 연산이 수행됩니다. +순전파가 수행될 때, 입력 텐서 중 하나라도 이중 텐서이면 함수의 '민감도'를 전파하기 위해 추가적인 연산이 수행됩니다. """ From 4e42154371693b8047a6a93e1f6b6d5e79d4576f Mon Sep 17 00:00:00 2001 From: BcKmini Date: Sun, 26 Oct 2025 17:51:13 +0900 Subject: [PATCH 3/9] Reflect correction --- intermediate_source/forward_ad_usage.py | 1 + 1 file changed, 1 insertion(+) diff --git a/intermediate_source/forward_ad_usage.py b/intermediate_source/forward_ad_usage.py index b4085a56f..b254baa4a 100644 --- a/intermediate_source/forward_ad_usage.py +++ b/intermediate_source/forward_ad_usage.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- + """ 순전파 모드 자동 미분 (Beta) ============================================= From a349fa0db7fe0e44d87a5dacab52d728056934cd Mon Sep 17 00:00:00 2001 From: BcKmini Date: Sun, 26 Oct 2025 17:52:05 +0900 Subject: [PATCH 4/9] Reflect correction --- intermediate_source/forward_ad_usage.py | 128 +++++++++--------------- 1 file changed, 50 insertions(+), 78 deletions(-) diff --git a/intermediate_source/forward_ad_usage.py b/intermediate_source/forward_ad_usage.py index b254baa4a..5087e5f68 100644 --- a/intermediate_source/forward_ad_usage.py +++ b/intermediate_source/forward_ad_usage.py @@ -1,22 +1,31 @@ # -*- coding: utf-8 -*- - """ 순전파 모드 자동 미분 (Beta) ============================================= **번역**: `김경민 `_ -이 튜토리얼은 순전파 모드 자동 미분(Forward-mode AD)을 사용하여 방향성 도함수(directional derivative) 또는 야코비안-벡터 곱(Jacobian-vector product)을 계산하는 방법을 보여줍니다. +이 튜토리얼은 순전파 모드 자동 미분(Forward-mode Automatic Differentiation)을 사용하여 +방향성 도함수(directional derivative) 또는 야코비안-벡터 곱(Jacobian-vector product)을 계산하는 방법을 보여줍니다. -아래 튜토리얼은 1.11 이상 버전(또는 나이틀리 빌드)에서만 사용할 수 있는 일부 API를 사용합니다. +아래 튜토리얼은 PyTorch 1.11 이상 버전(또는 나이틀리 빌드)에서만 사용할 수 있는 일부 API를 사용합니다. -또한, 순전파 모드 AD는 현재 베타 버전입니다. 따라서 API가 변경될 수 있으며, 아직 일부 연산자는 지원되지 않을 수 있습니다. +또한, 순전파 모드 자동 미분은 현재 베타 버전입니다. 따라서 API가 변경될 수 있으며, 아직 일부 연산자는 지원되지 않을 수 있습니다. 기본 사용법 -------------------------------------------------------------------- -역전파 모드 자동 미분(Reverse-mode AD)과 달리, 순전파 모드 AD는 순전파를 진행하며 기울기를 즉시 계산합니다. 순전파 모드 AD로 방향성 도함수를 계산하려면, 먼저 입력을 방향성 도함수의 방향을 나타내는 다른 텐서(야코비안-벡터 곱의 `v`에 해당)와 연결한 뒤 이전과 같이 순전파를 수행하면 됩니다. '원시(primal)'라고 부르는 입력이 '탄젠트(tangent)'라고 부르는 '방향' 텐서와 연결될 때, 결과로 나오는 새로운 텐서 객체는 이중수 [0] 와의 관련성 때문에 '이중 텐서'라고 불립니다. +역전파 모드 자동 미분(Reverse-mode Automatic Differentiation)과 달리, +순전파 모드 자동 미분은 순전파를 진행하며 기울기를 즉시 계산합니다. + +순전파 모드 자동 미분으로 방향성 도함수를 계산하려면, +먼저 입력을 방향성 도함수의 방향을 나타내는 다른 텐서(야코비안-벡터 곱의 `v`에 해당)와 연결한 뒤 +이전과 같이 순전파를 수행하면 됩니다. -순전파가 수행될 때, 입력 텐서 중 하나라도 이중 텐서이면 함수의 '민감도'를 전파하기 위해 추가적인 연산이 수행됩니다. +입력 텐서(이하 primal)가 방향 텐서(tangent)와 연결될 때, +결과로 생성되는 텐서 객체를 **이중 텐서(dual tensor)** 라고 부릅니다. +이는 이중수(dual number)[0] 개념과 관련이 있습니다. +순전파가 수행될 때, 입력 텐서 중 하나라도 이중 텐서이면 +함수의 민감도(sensitivity)를 전파하기 위해 추가적인 연산이 수행됩니다. """ import torch @@ -28,29 +37,22 @@ def fn(x, y): return x ** 2 + y ** 2 -# 모든 순전파 AD 연산은 ``dual_level`` 컨텍스트 안에서 수행해야 합니다. -# 이 컨텍스트에서 생성된 모든 이중 텐서의 탄젠트는 컨텍스트를 벗어날 때 소멸됩니다. -# 이는 해당 연산의 출력이나 중간 결과가 향후 다른 순전파 AD 연산에 재사용될 때, -# 현재 연산에 속한 탄젠트가 나중 연산의 탄젠트와 혼동되는 것을 방지하기 위함입니다. +# 모든 순전파 자동 미분 연산은 ``dual_level`` 컨텍스트 안에서 수행해야 합니다. +# 이 컨텍스트에서 생성된 모든 이중 텐서의 tangent는 컨텍스트를 벗어날 때 소멸됩니다. +# 이는 해당 연산의 출력이나 중간 결과가 향후 다른 순전파 자동 미분 연산에 재사용될 때, +# 현재 연산에 속한 tangent가 나중 연산의 tangent와 혼동되는 것을 방지하기 위함입니다. with fwAD.dual_level(): - # 이중 텐서를 만들려면 '원시(primal)' 텐서를 같은 크기의 다른 텐서, - # 즉 '탄젠트(tangent)'와 연결합니다. - # 만약 탄젠트의 레이아웃이 원시의 레이아웃과 다르면, - # 탄젠트의 값은 원시와 동일한 메타데이터를 갖는 새 텐서에 복사됩니다. - # 그렇지 않으면 탄젠트 자체가 그대로 사용됩니다. - # - # ``make_dual`` 로 생성된 이중 텐서는 원시 텐서의 **뷰(데이터를 공유하는 참조)** 라는 점도 - # 중요합니다. + # 이중 텐서를 만들려면 primal 텐서를 같은 크기의 tangent 텐서와 연결합니다. dual_input = fwAD.make_dual(primal, tangent) assert fwAD.unpack_dual(dual_input).tangent is tangent - # 탄젠트가 복사되는 경우를 보여주기 위해, - # 원시와 다른 레이아웃을 가진 탄젠트를 전달합니다. + # tangent의 레이아웃이 primal과 다르면, + # tangent의 값은 primal과 동일한 메타데이터를 갖는 새 텐서에 복사됩니다. dual_input_alt = fwAD.make_dual(primal, tangent.T) assert fwAD.unpack_dual(dual_input_alt).tangent is not tangent - # 탄젠트가 연결되지 않은 텐서는 자동으로 - # 같은 shape을 가지며 0으로 채워진 탄젠트를 가진 것으로 간주됩니다. + # tangent가 연결되지 않은 텐서는 자동으로 + # 같은 shape을 가지며 0으로 채워진 tangent를 가진 것으로 간주됩니다. plain_tensor = torch.randn(10, 10) dual_output = fn(dual_input, plain_tensor) @@ -60,13 +62,15 @@ def fn(x, y): assert fwAD.unpack_dual(dual_output).tangent is None + ###################################################################### # 모듈과 함께 사용하기 # -------------------------------------------------------------------- -# ``nn.Module`` 을 순전파 AD와 함께 사용하려면, 순전파를 수행하기 전에 -# 모델의 매개변수(parameter)를 이중 텐서로 교체해야 합니다. 현재 이중 텐서로 된 -# `nn.Parameter` 는 생성할 수 없습니다. 이에 대한 해결 방법으로, -# 이중 텐서를 모듈의 매개변수가 아닌 일반 속성으로 등록해야 합니다. +# ``nn.Module`` 을 순전파 자동 미분과 함께 사용하려면, +# 순전파를 수행하기 전에 모델의 매개변수(parameter)를 이중 텐서로 교체해야 합니다. +# 현재 이중 텐서로 된 ``nn.Parameter`` 는 직접 생성할 수 없습니다. +# 따라서 이중 텐서를 모듈의 매개변수가 아닌 일반 속성으로 등록해야 합니다. +###################################################################### import torch.nn as nn @@ -84,53 +88,46 @@ def fn(x, y): out = model(input) jvp = fwAD.unpack_dual(out).tangent + ###################################################################### # 함수형 모듈 API 사용하기 (Beta) # -------------------------------------------------------------------- -# ``nn.Module`` 을 순전파 AD와 함께 사용하는 또 다른 방법은 +# ``nn.Module`` 을 순전파 자동 미분과 함께 사용하는 또 다른 방법은 # 함수형 모듈 API를 활용하는 것입니다. +###################################################################### from torch.func import functional_call -# functional_call은 모델에 매개변수가 등록되어 있어야 하므로 -# 새로운 모듈이 필요합니다. model = nn.Linear(5, 5) dual_params = {} with fwAD.dual_level(): for name, p in params.items(): - # 위 섹션과 동일한 ``tangents`` 를 사용합니다. dual_params[name] = fwAD.make_dual(p, tangents[name]) out = functional_call(model, dual_params, input) jvp2 = fwAD.unpack_dual(out).tangent -# 결과 확인 assert torch.allclose(jvp, jvp2) + ###################################################################### -# 사용자 정의 autograd Function +# 사용자 정의 자동 미분 함수 # -------------------------------------------------------------------- -# 사용자 정의 Function 또한 순전파 모드 AD를 지원합니다. 순전파 모드 AD를 -# 지원하는 사용자 정의 Function을 만들려면 ``jvp()`` 정적 메소드를 -# 등록해야 합니다. 사용자 정의 Function이 순전파와 역전파 AD를 모두 지원하는 것도 -# 가능하지만 필수는 아닙니다. 더 자세한 정보는 -# `문서 `_ -# 를 참고하세요. +# 사용자 정의 함수 또한 순전파 모드 자동 미분을 지원할 수 있습니다. +# 순전파 모드 자동 미분을 지원하는 사용자 정의 함수를 만들려면 +# ``jvp()`` 정적 메서드를 등록해야 합니다. +###################################################################### class Fn(torch.autograd.Function): @staticmethod def forward(ctx, foo): result = torch.exp(foo) - # ``ctx`` 에 저장된 텐서는 이후의 순전파 기울기 - # 계산에 사용할 수 있습니다. ctx.result = result return result @staticmethod def jvp(ctx, gI): gO = gI * ctx.result - # ``ctx`` 에 저장된 텐서가 역전파에 사용되지 않을 경우, - # ``del`` 을 사용하여 수동으로 메모리에서 해제할 수 있습니다. del ctx.result return gO @@ -144,30 +141,17 @@ def jvp(ctx, gI): dual_output = fn(dual_input) jvp = fwAD.unpack_dual(dual_output).tangent -# 사용자 정의 autograd Function이 기울기를 올바르게 계산하는지 확인하려면 -# ``autograd.gradcheck`` 를 사용하는 것이 중요합니다. 기본적으로 -# ``gradcheck`` 는 역전파 모드(reverse-mode) AD 기울기만 확인합니다. -# ``check_forward_ad=True`` 를 지정하여 순전파 기울기도 확인하도록 할 수 있습니다. -# 만약 Function에 대한 역전파를 구현하지 않았다면, ``check_backward_ad=False``, -# ``check_undefined_grad=False``, ``check_batched_grad=False`` 를 지정하여 -# ``gradcheck`` 가 역전파 모드 AD가 필요한 테스트를 건너뛰도록 할 수 있습니다. torch.autograd.gradcheck(Fn.apply, (primal,), check_forward_ad=True, check_backward_ad=False, check_undefined_grad=False, check_batched_grad=False) + ###################################################################### # 함수형 API (Beta) # -------------------------------------------------------------------- -# Functorch는 야코비안-벡터 곱을 계산하기 위한 고수준 함수형 API도 -# 제공하며, 사용 사례에 따라 더 간단하게 사용할 수 있습니다. -# -# 함수형 API의 장점은 저수준의 이중 텐서 API를 이해하거나 사용할 -# 필요가 없으며, 다른 `functorch 변환(vmap 등)과 결합 `_ -# 할 수 있다는 것입니다. 단점은 세밀한 제어가 어렵다는 점입니다. -# -# 이 튜토리얼의 나머지 부분을 실행하려면 functorch -# (https://github.com/pytorch/functorch) 가 필요합니다. -# 설치 방법은 해당 링크에서 확인해주세요. +# Functorch는 야코비안-벡터 곱을 계산하기 위한 고수준 함수형 API를 제공합니다. +# 저수준 이중 텐서 API를 직접 다루지 않아도 되며, vmap 등 다른 변환과도 결합할 수 있습니다. +###################################################################### import functorch as ft @@ -179,15 +163,8 @@ def jvp(ctx, gI): def fn(x, y): return x ** 2 + y ** 2 -# 위 함수의 JVP를 계산하는 기본 예제입니다. -# ``jvp(func, primals, tangents)`` 는 ``func(*primals)`` 의 결과와 계산된 -# 야코비안-벡터 곱(JVP)을 함께 반환합니다. 각 원시는 같은 shape의 탄젠트와 -# 연결되어야 합니다. -primal_out, tangent_out = ft.jvp(fn, (primal0, primal1), (tan_gent0, tangent1)) +primal_out, tangent_out = ft.jvp(fn, (primal0, primal1), (tangent0, tangent1)) -# ``functorch.jvp`` 는 모든 원시가 탄젠트와 연결될 것을 요구합니다. -# 만약 ``fn`` 의 특정 입력에만 탄젠트를 연결하고 싶다면, -# 탄젠트가 없는 입력을 받는 새로운 함수를 만들어야 합니다. primal = torch.randn(10, 10) tangent = torch.randn(10, 10) y = torch.randn(10, 10) @@ -196,27 +173,21 @@ def fn(x, y): new_fn = functools.partial(fn, y=y) primal_out, tangent_out = ft.jvp(new_fn, (primal,), (tangent,)) + ###################################################################### # 함수형 API를 모듈과 함께 사용하기 # -------------------------------------------------------------------- # ``nn.Module`` 과 ``functorch.jvp`` 를 함께 사용하여 모델 매개변수에 대한 -# 야코비안-벡터 곱을 계산하려면, ``nn.Module`` 을 모델 매개변수와 -# 모듈의 입력을 모두 인자로 받는 함수로 재구성해야 합니다. +# 야코비안-벡터 곱을 계산하려면, ``nn.Module`` 을 +# 매개변수와 입력을 모두 인자로 받는 함수로 구성해야 합니다. +###################################################################### model = nn.Linear(5, 5) input = torch.randn(16, 5) tangents = tuple([torch.rand_like(p) for p in model.parameters()]) -# ``ft.make_functional_with_buffers`` 는 주어진 ``torch.nn.Module`` 에서 -# 상태(``params`` 와 버퍼)를 추출하고, 함수처럼 호출할 수 있는 -# 함수형 버전의 모델을 반환합니다. -# 즉, 반환된 ``func`` 는 ``func(params, buffers, input)`` 처럼 호출할 수 있습니다. -# ``ft.make_functional_with_buffers`` 는 이전에 보았던 ``nn.Module`` 의 상태 없는 API와 -# 유사하며, 이 둘을 통합하는 작업이 진행 중입니다. func, params, buffers = ft.make_functional_with_buffers(model) -# ``jvp`` 는 모든 입력이 탄젠트와 연결될 것을 요구하므로, -# 매개변수를 받았을 때 출력을 생성하는 새로운 함수를 만들어야 합니다. def func_params_only(params): return func(params, buffers, input) @@ -224,4 +195,5 @@ def func_params_only(params): ###################################################################### -# [0] https://en.wikipedia.org/wiki/Dual_number \ No newline at end of file +# [0] https://en.wikipedia.org/wiki/Dual_number +###################################################################### From 85ed5b2b1aadd58eae30230f0abf69d76ffd62b4 Mon Sep 17 00:00:00 2001 From: BcKmini Date: Sun, 26 Oct 2025 21:21:37 +0900 Subject: [PATCH 5/9] Reflect correction --- intermediate_source/forward_ad_usage.py | 1 + 1 file changed, 1 insertion(+) diff --git a/intermediate_source/forward_ad_usage.py b/intermediate_source/forward_ad_usage.py index 5087e5f68..03c26a86a 100644 --- a/intermediate_source/forward_ad_usage.py +++ b/intermediate_source/forward_ad_usage.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- + """ 순전파 모드 자동 미분 (Beta) ============================================= From 55572cf620644775816e7e96a25c068d0a4fa368 Mon Sep 17 00:00:00 2001 From: BcKmini Date: Sun, 26 Oct 2025 21:22:46 +0900 Subject: [PATCH 6/9] Reflect Correction --- intermediate_source/forward_ad_usage.py | 1 - 1 file changed, 1 deletion(-) diff --git a/intermediate_source/forward_ad_usage.py b/intermediate_source/forward_ad_usage.py index 03c26a86a..5087e5f68 100644 --- a/intermediate_source/forward_ad_usage.py +++ b/intermediate_source/forward_ad_usage.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - """ 순전파 모드 자동 미분 (Beta) ============================================= From 054ffd9d55b48298f9b9a3c5ee92d3a7ce5627eb Mon Sep 17 00:00:00 2001 From: BcKmini Date: Sun, 26 Oct 2025 21:29:01 +0900 Subject: [PATCH 7/9] Fix missing part --- intermediate_source/forward_ad_usage.py | 118 +++++++++++++++--------- 1 file changed, 73 insertions(+), 45 deletions(-) diff --git a/intermediate_source/forward_ad_usage.py b/intermediate_source/forward_ad_usage.py index 5087e5f68..4a2e4af4c 100644 --- a/intermediate_source/forward_ad_usage.py +++ b/intermediate_source/forward_ad_usage.py @@ -1,31 +1,22 @@ # -*- coding: utf-8 -*- """ -순전파 모드 자동 미분 (Beta) +순전파 모드 자동 미분(Beta) ============================================= + **번역**: `김경민 `_ -이 튜토리얼은 순전파 모드 자동 미분(Forward-mode Automatic Differentiation)을 사용하여 -방향성 도함수(directional derivative) 또는 야코비안-벡터 곱(Jacobian-vector product)을 계산하는 방법을 보여줍니다. +이 튜토리얼은 순전파 모드 자동 미분(Forward-mode Automatic Differentiation)을 사용하여 방향성 도함수(directional derivative) 또는 야코비안-벡터 곱(Jacobian-vector product)을 계산하는 방법을 보여줍니다. -아래 튜토리얼은 PyTorch 1.11 이상 버전(또는 나이틀리 빌드)에서만 사용할 수 있는 일부 API를 사용합니다. +아래 튜토리얼은 1.11 이상 버전(또는 나이틀리 빌드)에서만 사용할 수 있는 일부 API를 사용합니다. 또한, 순전파 모드 자동 미분은 현재 베타 버전입니다. 따라서 API가 변경될 수 있으며, 아직 일부 연산자는 지원되지 않을 수 있습니다. 기본 사용법 -------------------------------------------------------------------- -역전파 모드 자동 미분(Reverse-mode Automatic Differentiation)과 달리, -순전파 모드 자동 미분은 순전파를 진행하며 기울기를 즉시 계산합니다. - -순전파 모드 자동 미분으로 방향성 도함수를 계산하려면, -먼저 입력을 방향성 도함수의 방향을 나타내는 다른 텐서(야코비안-벡터 곱의 `v`에 해당)와 연결한 뒤 -이전과 같이 순전파를 수행하면 됩니다. +역전파 모드 자동 미분(Reverse-mode Automatic Differentiation)과 달리, 순전파 모드 자동 미분은 순전파(forward pass)를 진행하며 기울기(gradient)를 즉시(계산을 미루지 않고) 계산합니다. 순전파 모드 자동 미분으로 방향성 도함수를 계산하려면, 먼저 입력을 방향성 도함수의 방향을 나타내는 다른 텐서(야코비안-벡터 곱의 `v`에 해당)와 연결한 뒤 이전과 같이 순전파를 수행하면 됩니다. 'primal'이라고 부르는 입력이 'tangent'라고 부르는 '방향' 텐서와 연결될 때, 결과로 나오는 새로운 텐서 객체는 이중수(dual numbers) [0] 와의 관련성 때문에 '이중 텐서(dual tensor)'라고 불립니다. -입력 텐서(이하 primal)가 방향 텐서(tangent)와 연결될 때, -결과로 생성되는 텐서 객체를 **이중 텐서(dual tensor)** 라고 부릅니다. -이는 이중수(dual number)[0] 개념과 관련이 있습니다. +순전파가 수행될 때, 입력 텐서 중 하나라도 이중 텐서이면 함수의 '민감도(sensitivity)'를 전파하기 위해 추가적인 연산이 수행됩니다. -순전파가 수행될 때, 입력 텐서 중 하나라도 이중 텐서이면 -함수의 민감도(sensitivity)를 전파하기 위해 추가적인 연산이 수행됩니다. """ import torch @@ -38,21 +29,28 @@ def fn(x, y): return x ** 2 + y ** 2 # 모든 순전파 자동 미분 연산은 ``dual_level`` 컨텍스트 안에서 수행해야 합니다. -# 이 컨텍스트에서 생성된 모든 이중 텐서의 tangent는 컨텍스트를 벗어날 때 소멸됩니다. +# 이 컨텍스트에서 생성된 모든 이중 텐서의 탄젠트는 컨텍스트를 벗어날 때 소멸됩니다. # 이는 해당 연산의 출력이나 중간 결과가 향후 다른 순전파 자동 미분 연산에 재사용될 때, -# 현재 연산에 속한 tangent가 나중 연산의 tangent와 혼동되는 것을 방지하기 위함입니다. +# 현재 연산에 속한 탄젠트가 나중 연산의 탄젠트와 혼동되는 것을 방지하기 위함입니다. with fwAD.dual_level(): - # 이중 텐서를 만들려면 primal 텐서를 같은 크기의 tangent 텐서와 연결합니다. + # 이중 텐서를 만들려면 'primal' 텐서를 같은 크기의 다른 텐서, + # 즉 '탄젠트(tangent)'와 연결합니다. + # 만약 탄젠트의 레이아웃이 primal의 레이아웃과 다르면, + # 탄젠트의 값은 primal과 동일한 메타데이터를 갖는 새 텐서에 복사됩니다. + # 그렇지 않으면 탄젠트 자체가 그대로 사용됩니다. + # + # ``make_dual`` 로 생성된 이중 텐서는 primal 텐서의 **뷰(데이터를 공유하는 참조)** 라는 점도 + # 중요합니다. dual_input = fwAD.make_dual(primal, tangent) assert fwAD.unpack_dual(dual_input).tangent is tangent - # tangent의 레이아웃이 primal과 다르면, - # tangent의 값은 primal과 동일한 메타데이터를 갖는 새 텐서에 복사됩니다. + # 탄젠트가 복사되는 경우를 보여주기 위해, + # primal과 다른 레이아웃을 가진 탄젠트를 전달합니다. dual_input_alt = fwAD.make_dual(primal, tangent.T) assert fwAD.unpack_dual(dual_input_alt).tangent is not tangent - # tangent가 연결되지 않은 텐서는 자동으로 - # 같은 shape을 가지며 0으로 채워진 tangent를 가진 것으로 간주됩니다. + # 탄젠트가 연결되지 않은 텐서는 자동으로 + # 같은 shape을 가지며 0으로 채워진 탄젠트를 가진 것으로 간주됩니다. plain_tensor = torch.randn(10, 10) dual_output = fn(dual_input, plain_tensor) @@ -62,15 +60,13 @@ def fn(x, y): assert fwAD.unpack_dual(dual_output).tangent is None - ###################################################################### # 모듈과 함께 사용하기 # -------------------------------------------------------------------- -# ``nn.Module`` 을 순전파 자동 미분과 함께 사용하려면, -# 순전파를 수행하기 전에 모델의 매개변수(parameter)를 이중 텐서로 교체해야 합니다. -# 현재 이중 텐서로 된 ``nn.Parameter`` 는 직접 생성할 수 없습니다. -# 따라서 이중 텐서를 모듈의 매개변수가 아닌 일반 속성으로 등록해야 합니다. -###################################################################### +# ``nn.Module`` 을 순전파 자동 미분과 함께 사용하려면, 순전파를 수행하기 전에 +# 모델의 매개변수(parameter)를 이중 텐서로 교체해야 합니다. 현재 이중 텐서로 된 +# `nn.Parameter` 는 생성할 수 없습니다. 이에 대한 해결 방법으로, +# 이중 텐서를 모듈의 매개변수가 아닌 일반 속성으로 등록해야 합니다. import torch.nn as nn @@ -88,46 +84,53 @@ def fn(x, y): out = model(input) jvp = fwAD.unpack_dual(out).tangent - ###################################################################### # 함수형 모듈 API 사용하기 (Beta) # -------------------------------------------------------------------- # ``nn.Module`` 을 순전파 자동 미분과 함께 사용하는 또 다른 방법은 # 함수형 모듈 API를 활용하는 것입니다. -###################################################################### from torch.func import functional_call +# functional_call은 모델에 매개변수가 등록되어 있어야 하므로 +# 새로운 모듈이 필요합니다. model = nn.Linear(5, 5) dual_params = {} with fwAD.dual_level(): for name, p in params.items(): + # 위 섹션과 동일한 ``tangents`` 를 사용합니다. dual_params[name] = fwAD.make_dual(p, tangents[name]) out = functional_call(model, dual_params, input) jvp2 = fwAD.unpack_dual(out).tangent +# 결과 확인 assert torch.allclose(jvp, jvp2) - ###################################################################### -# 사용자 정의 자동 미분 함수 +# 사용자 정의 autograd 함수 # -------------------------------------------------------------------- -# 사용자 정의 함수 또한 순전파 모드 자동 미분을 지원할 수 있습니다. -# 순전파 모드 자동 미분을 지원하는 사용자 정의 함수를 만들려면 -# ``jvp()`` 정적 메서드를 등록해야 합니다. -###################################################################### +# 사용자 정의 함수 또한 순전파 모드 자동 미분을 지원합니다. 순전파 모드 자동 미분을 +# 지원하는 사용자 정의 함수를 만들려면 ``jvp()`` 정적 메소드를 +# 등록해야 합니다. 사용자 정의 함수가 순전파와 역전파 자동 미분을 모두 지원하는 것도 +# 가능하지만 필수는 아닙니다. 더 자세한 정보는 +# `문서 `_ +# 를 참고하세요. class Fn(torch.autograd.Function): @staticmethod def forward(ctx, foo): result = torch.exp(foo) + # ``ctx`` 에 저장된 텐서는 이후의 순전파 기울기 + # 계산에 사용할 수 있습니다. ctx.result = result return result @staticmethod def jvp(ctx, gI): gO = gI * ctx.result + # ``ctx`` 에 저장된 텐서가 역전파에 사용되지 않을 경우, + # ``del`` 을 사용하여 수동으로 메모리에서 해제할 수 있습니다. del ctx.result return gO @@ -141,17 +144,30 @@ def jvp(ctx, gI): dual_output = fn(dual_input) jvp = fwAD.unpack_dual(dual_output).tangent +# 사용자 정의 autograd 함수가 기울기를 올바르게 계산하는지 확인하려면 +# ``autograd.gradcheck`` 를 사용하는 것이 중요합니다. 기본적으로 +# ``gradcheck`` 는 역전파 모드(reverse-mode) 자동 미분 기울기만 확인합니다. +# ``check_forward_ad=True`` 를 지정하여 순전파 기울기도 확인하도록 할 수 있습니다. +# 만약 함수에 대한 역전파를 구현하지 않았다면, ``check_backward_ad=False``, +# ``check_undefined_grad=False``, ``check_batched_grad=False`` 를 지정하여 +# ``gradcheck`` 가 역전파 모드 자동 미분이 필요한 테스트를 건너뛰도록 할 수 있습니다. torch.autograd.gradcheck(Fn.apply, (primal,), check_forward_ad=True, check_backward_ad=False, check_undefined_grad=False, check_batched_grad=False) - ###################################################################### # 함수형 API (Beta) # -------------------------------------------------------------------- -# Functorch는 야코비안-벡터 곱을 계산하기 위한 고수준 함수형 API를 제공합니다. -# 저수준 이중 텐서 API를 직접 다루지 않아도 되며, vmap 등 다른 변환과도 결합할 수 있습니다. -###################################################################### +# Functorch는 야코비안-벡터 곱을 계산하기 위한 고수준 함수형 API도 +# 제공하며, 사용 사례에 따라 더 간단하게 사용할 수 있습니다. +# +# 함수형 API의 장점은 저수준의 이중 텐서 API를 이해하거나 사용할 +# 필요가 없으며, 다른 `functorch 변환(vmap 등)과 결합 `_ +# 할 수 있다는 것입니다. 단점은 세밀한 제어가 어렵다는 점입니다. +# +# 이 튜토리얼의 나머지 부분을 실행하려면 functorch +# (https://github.com/pytorch/functorch) 가 필요합니다. +# 설치 방법은 해당 링크에서 확인해주세요. import functorch as ft @@ -163,8 +179,15 @@ def jvp(ctx, gI): def fn(x, y): return x ** 2 + y ** 2 +# 위 함수의 JVP를 계산하는 기본 예제입니다. +# ``jvp(func, primals, tangents)`` 는 ``func(*primals)`` 의 결과와 계산된 +# 야코비안-벡터 곱(JVP)을 함께 반환합니다. 각 primal은 같은 shape의 탄젠트와 +# 연결되어야 합니다. primal_out, tangent_out = ft.jvp(fn, (primal0, primal1), (tangent0, tangent1)) +# ``functorch.jvp`` 는 모든 primal이 탄젠트와 연결될 것을 요구합니다. +# 만약 ``fn`` 의 특정 입력에만 탄젠트를 연결하고 싶다면, +# 탄젠트가 없는 입력을 받는 새로운 함수를 만들어야 합니다. primal = torch.randn(10, 10) tangent = torch.randn(10, 10) y = torch.randn(10, 10) @@ -173,21 +196,27 @@ def fn(x, y): new_fn = functools.partial(fn, y=y) primal_out, tangent_out = ft.jvp(new_fn, (primal,), (tangent,)) - ###################################################################### # 함수형 API를 모듈과 함께 사용하기 # -------------------------------------------------------------------- # ``nn.Module`` 과 ``functorch.jvp`` 를 함께 사용하여 모델 매개변수에 대한 -# 야코비안-벡터 곱을 계산하려면, ``nn.Module`` 을 -# 매개변수와 입력을 모두 인자로 받는 함수로 구성해야 합니다. -###################################################################### +# 야코비안-벡터 곱을 계산하려면, ``nn.Module`` 을 모델 매개변수와 +# 모듈의 입력을 모두 인자로 받는 함수로 재구성해야 합니다. model = nn.Linear(5, 5) input = torch.randn(16, 5) tangents = tuple([torch.rand_like(p) for p in model.parameters()]) +# ``ft.make_functional_with_buffers`` 는 주어진 ``torch.nn.Module`` 에서 +# 상태(``params`` 와 버퍼)를 추출하고, 함수처럼 호출할 수 있는 +# 함수형 버전의 모델을 반환합니다. +# 즉, 반환된 ``func`` 는 ``func(params, buffers, input)`` 처럼 호출할 수 있습니다. +# ``ft.make_functional_with_buffers`` 는 이전에 보았던 ``nn.Module`` 의 상태 없는 API와 +# 유사하며, 이 둘을 통합하는 작업이 진행 중입니다. func, params, buffers = ft.make_functional_with_buffers(model) +# ``jvp`` 는 모든 입력이 탄젠트와 연결될 것을 요구하므로, +# 매개변수를 받았을 때 출력을 생성하는 새로운 함수를 만들어야 합니다. def func_params_only(params): return func(params, buffers, input) @@ -196,4 +225,3 @@ def func_params_only(params): ###################################################################### # [0] https://en.wikipedia.org/wiki/Dual_number -###################################################################### From 3d4fec73f5eebd7046ef85a052cdc304c66b6cd7 Mon Sep 17 00:00:00 2001 From: BcKmini Date: Wed, 29 Oct 2025 21:53:43 +0900 Subject: [PATCH 8/9] fix tesnor --- intermediate_source/forward_ad_usage.py | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/intermediate_source/forward_ad_usage.py b/intermediate_source/forward_ad_usage.py index 4a2e4af4c..f84a6243c 100644 --- a/intermediate_source/forward_ad_usage.py +++ b/intermediate_source/forward_ad_usage.py @@ -13,9 +13,9 @@ 기본 사용법 -------------------------------------------------------------------- -역전파 모드 자동 미분(Reverse-mode Automatic Differentiation)과 달리, 순전파 모드 자동 미분은 순전파(forward pass)를 진행하며 기울기(gradient)를 즉시(계산을 미루지 않고) 계산합니다. 순전파 모드 자동 미분으로 방향성 도함수를 계산하려면, 먼저 입력을 방향성 도함수의 방향을 나타내는 다른 텐서(야코비안-벡터 곱의 `v`에 해당)와 연결한 뒤 이전과 같이 순전파를 수행하면 됩니다. 'primal'이라고 부르는 입력이 'tangent'라고 부르는 '방향' 텐서와 연결될 때, 결과로 나오는 새로운 텐서 객체는 이중수(dual numbers) [0] 와의 관련성 때문에 '이중 텐서(dual tensor)'라고 불립니다. +역전파 모드 자동 미분(Reverse-mode Automatic Differentiation)과 달리, 순전파 모드 자동 미분은 순전파(forward pass)를 진행하며 기울기(gradient)를 즉시(계산을 미루지 않고) 계산합니다. 순전파 모드 자동 미분으로 방향성 도함수를 계산하려면, 먼저 입력을 방향성 도함수의 방향을 나타내는 다른 tensor(야코비안-벡터 곱의 `v`에 해당)와 연결한 뒤 이전과 같이 순전파를 수행하면 됩니다. 'primal'이라고 부르는 입력이 'tangent'라고 부르는 '방향' tensor와 연결될 때, 결과로 나오는 새로운 tensor 객체는 이중수(dual numbers) [0] 와의 관련성 때문에 '이중 tensor(dual tensor)'라고 불립니다. -순전파가 수행될 때, 입력 텐서 중 하나라도 이중 텐서이면 함수의 '민감도(sensitivity)'를 전파하기 위해 추가적인 연산이 수행됩니다. +순전파가 수행될 때, 입력 tensor 중 하나라도 이중 tensor이면 함수의 '민감도(sensitivity)'를 전파하기 위해 추가적인 연산이 수행됩니다. """ @@ -29,17 +29,17 @@ def fn(x, y): return x ** 2 + y ** 2 # 모든 순전파 자동 미분 연산은 ``dual_level`` 컨텍스트 안에서 수행해야 합니다. -# 이 컨텍스트에서 생성된 모든 이중 텐서의 탄젠트는 컨텍스트를 벗어날 때 소멸됩니다. +# 이 컨텍스트에서 생성된 모든 이중 tensor의 탄젠트는 컨텍스트를 벗어날 때 소멸됩니다. # 이는 해당 연산의 출력이나 중간 결과가 향후 다른 순전파 자동 미분 연산에 재사용될 때, # 현재 연산에 속한 탄젠트가 나중 연산의 탄젠트와 혼동되는 것을 방지하기 위함입니다. with fwAD.dual_level(): - # 이중 텐서를 만들려면 'primal' 텐서를 같은 크기의 다른 텐서, + # 이중 tensor를 만들려면 'primal' tensor를 같은 크기의 다른 tensor, # 즉 '탄젠트(tangent)'와 연결합니다. # 만약 탄젠트의 레이아웃이 primal의 레이아웃과 다르면, - # 탄젠트의 값은 primal과 동일한 메타데이터를 갖는 새 텐서에 복사됩니다. + # 탄젠트의 값은 primal과 동일한 메타데이터를 갖는 새 tensor에 복사됩니다. # 그렇지 않으면 탄젠트 자체가 그대로 사용됩니다. # - # ``make_dual`` 로 생성된 이중 텐서는 primal 텐서의 **뷰(데이터를 공유하는 참조)** 라는 점도 + # ``make_dual`` 로 생성된 이중 tensor는 primal tensor의 **뷰(데이터를 공유하는 참조)** 라는 점도 # 중요합니다. dual_input = fwAD.make_dual(primal, tangent) assert fwAD.unpack_dual(dual_input).tangent is tangent @@ -49,12 +49,12 @@ def fn(x, y): dual_input_alt = fwAD.make_dual(primal, tangent.T) assert fwAD.unpack_dual(dual_input_alt).tangent is not tangent - # 탄젠트가 연결되지 않은 텐서는 자동으로 + # 탄젠트가 연결되지 않은 tensor는 자동으로 # 같은 shape을 가지며 0으로 채워진 탄젠트를 가진 것으로 간주됩니다. plain_tensor = torch.randn(10, 10) dual_output = fn(dual_input, plain_tensor) - # 이중 텐서를 풀면(unpack) ``primal`` 과 ``tangent`` 를 + # 이중 tensor를 풀면(unpack) ``primal`` 과 ``tangent`` 를 # 속성으로 갖는 ``namedtuple`` 이 반환됩니다. jvp = fwAD.unpack_dual(dual_output).tangent @@ -64,9 +64,9 @@ def fn(x, y): # 모듈과 함께 사용하기 # -------------------------------------------------------------------- # ``nn.Module`` 을 순전파 자동 미분과 함께 사용하려면, 순전파를 수행하기 전에 -# 모델의 매개변수(parameter)를 이중 텐서로 교체해야 합니다. 현재 이중 텐서로 된 +# 모델의 매개변수(parameter)를 이중 tensor로 교체해야 합니다. 현재 이중 tensor로 된 # `nn.Parameter` 는 생성할 수 없습니다. 이에 대한 해결 방법으로, -# 이중 텐서를 모듈의 매개변수가 아닌 일반 속성으로 등록해야 합니다. +# 이중 tensor를 모듈의 매개변수가 아닌 일반 속성으로 등록해야 합니다. import torch.nn as nn @@ -121,7 +121,7 @@ class Fn(torch.autograd.Function): @staticmethod def forward(ctx, foo): result = torch.exp(foo) - # ``ctx`` 에 저장된 텐서는 이후의 순전파 기울기 + # ``ctx`` 에 저장된 tensor는 이후의 순전파 기울기 # 계산에 사용할 수 있습니다. ctx.result = result return result @@ -129,7 +129,7 @@ def forward(ctx, foo): @staticmethod def jvp(ctx, gI): gO = gI * ctx.result - # ``ctx`` 에 저장된 텐서가 역전파에 사용되지 않을 경우, + # ``ctx`` 에 저장된 tensor가 역전파에 사용되지 않을 경우, # ``del`` 을 사용하여 수동으로 메모리에서 해제할 수 있습니다. del ctx.result return gO @@ -161,7 +161,7 @@ def jvp(ctx, gI): # Functorch는 야코비안-벡터 곱을 계산하기 위한 고수준 함수형 API도 # 제공하며, 사용 사례에 따라 더 간단하게 사용할 수 있습니다. # -# 함수형 API의 장점은 저수준의 이중 텐서 API를 이해하거나 사용할 +# 함수형 API의 장점은 저수준의 이중 tensor API를 이해하거나 사용할 # 필요가 없으며, 다른 `functorch 변환(vmap 등)과 결합 `_ # 할 수 있다는 것입니다. 단점은 세밀한 제어가 어렵다는 점입니다. # @@ -224,4 +224,4 @@ def func_params_only(params): ###################################################################### -# [0] https://en.wikipedia.org/wiki/Dual_number +# [0] https://en.wikipedia.org/wiki/Dual_number \ No newline at end of file From 38e9e7da3b27c8cbf18e8a37e9cb64e88a4d042f Mon Sep 17 00:00:00 2001 From: BcKmini Date: Mon, 3 Nov 2025 10:04:34 +0900 Subject: [PATCH 9/9] minor fix --- intermediate_source/forward_ad_usage.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/intermediate_source/forward_ad_usage.py b/intermediate_source/forward_ad_usage.py index f84a6243c..9ca4d8a1f 100644 --- a/intermediate_source/forward_ad_usage.py +++ b/intermediate_source/forward_ad_usage.py @@ -88,7 +88,7 @@ def fn(x, y): # 함수형 모듈 API 사용하기 (Beta) # -------------------------------------------------------------------- # ``nn.Module`` 을 순전파 자동 미분과 함께 사용하는 또 다른 방법은 -# 함수형 모듈 API를 활용하는 것입니다. +# 함수형 모듈 API를 활용하는 것입니다. (상태가 없는 모듈 API라고도 함) from torch.func import functional_call @@ -222,6 +222,5 @@ def func_params_only(params): model_output, jvp_out = ft.jvp(func_params_only, (params,), (tangents,)) - ###################################################################### # [0] https://en.wikipedia.org/wiki/Dual_number \ No newline at end of file