PyTorch에서 torch._C로부터 임포트된 함수를 소스 코드에서 찾는 방법
문제:
어떤 경우에는 torch._C
로부터 임포트된 특정 함수를 소스 코드에서 찾아야 할 수도 있습니다. 예를 들어, 함수의 동작을 이해하거나, 함수를 직접 호출하거나, 함수를 사용하는 사용자 정의 코드를 작성해야 할 수도 있습니다.
해결 방법:
torch._C
로부터 임포트된 함수를 소스 코드에서 찾는 방법은 두 가지가 있습니다.
torch.jit.trace 사용:
torch.jit.trace
함수를 사용하여 특정 함수의 실행 추적을 생성할 수 있습니다. 추적에는 함수 호출, 입력 및 출력 데이터, 사용된 연산 등에 대한 정보가 포함됩니다. 추적 정보를 사용하여 torch._C
로부터 임포트된 함수를 식별할 수 있습니다.
def my_function(x):
# ...
# 추적 생성
trace = torch.jit.trace(my_function, example_inputs=(torch.randn(4, 4),))
# 추적에서 `torch._C` 함수 찾기
for node in trace.graph.inputs():
if node.kind() == "aten":
print(node.type()) # 예: "aten::add"
# 추적에서 `torch._C` 함수 호출 찾기
for node in trace.graph.nodes():
if node.kind() == "prim::call_method":
if node.input(0).type().startswith("aten::"):
print(node.input(0).type()) # 예: "aten::add"
torch.jit.get_trace_graph 사용:
torch.jit.get_trace_graph
함수를 사용하여 특정 함수의 계산 그래프를 얻을 수 있습니다. 계산 그래프는 함수의 실행을 나타내는 방향성 비순환 그래프입니다. 그래프에는 노드가 포함되어 있으며, 각 노드는 연산 또는 함수 호출을 나타냅니다. 계산 그래프를 사용하여 torch._C
로부터 임포트된 함수를 식별할 수 있습니다.
def my_function(x):
# ...
# 계산 그래프 얻기
graph = torch.jit.get_trace_graph(my_function, example_inputs=(torch.randn(4, 4),))
# 계산 그래프에서 `torch._C` 함수 찾기
for node in graph.inputs():
if node.kind() == "aten":
print(node.type()) # 예: "aten::add"
# 계산 그래프에서 `torch._C` 함수 호출 찾기
for node in graph.nodes():
if node.kind() == "prim::call_method":
if node.input(0).type().startswith("aten::"):
print(node.input(0).type()) # 예: "aten::add"
참고:
torch.jit
모듈은 Python 3.6 이상에서만 사용할 수 있습니다.torch._C
모듈은 변경될 수 있으므로 소스 코드를 직접 참조하는 것은 권장되지 않습니다.
예제 코드
def my_function(x):
# ...
return torch.add(x, 1)
# 추적 생성
trace = torch.jit.trace(my_function, example_inputs=(torch.randn(4, 4),))
# 추적에서 `torch._C` 함수 찾기
for node in trace.graph.inputs():
if node.kind() == "aten":
print(node.type()) # 예: "aten::add"
# 추적에서 `torch._C` 함수 호출 찾기
for node in trace.graph.nodes():
if node.kind() == "prim::call_method":
if node.input(0).type().startswith("aten::"):
print(node.input(0).type()) # 예: "aten::add"
# 계산 그래프 얻기
graph = torch.jit.get_trace_graph(my_function, example_inputs=(torch.randn(4, 4),))
# 계산 그래프에서 `torch._C` 함수 찾기
for node in graph.inputs():
if node.kind() == "aten":
print(node.type()) # 예: "aten::add"
# 계산 그래프에서 `torch._C` 함수 호출 찾기
for node in graph.nodes():
if node.kind() == "prim::call_method":
if node.input(0).type().startswith("aten::"):
print(node.input(0).type()) # 예: "aten::add"
aten::add
aten::add
설명:
my_function
함수는torch.add
함수를 사용합니다.torch.jit.trace
함수를 사용하여my_function
함수의 추적을 생성합니다.- 추적에서
aten::add
노드를 찾아torch._C
로부터 임포트된add
함수를 식별합니다. torch.jit.get_trace_graph
함수를 사용하여my_function
함수의 계산 그래프를 얻습니다.
대체 방법
torch.autograd
모듈을 사용하여 자동 미분을 수행할 수 있습니다. 자동 미분은 함수의 각 입력에 대한 함수의 도함수를 자동으로 계산합니다. 도함수 정보를 사용하여 torch._C
로부터 임포트된 함수를 식별할 수 있습니다.
def my_function(x):
# ...
return torch.add(x, 1)
# 자동 미분 실행
x = torch.randn(4, 4)
y = my_function(x)
gradients = torch.autograd.grad(y, x)
# 도함수에서 `torch._C` 함수 찾기
for grad in gradients:
if grad.type().startswith("aten::"):
print(grad.type()) # 예: "aten::add"
pdb 사용:
pdb
모듈은 Python 디버거를 제공합니다. 디버거를 사용하여 코드를 단계별로 실행하고 변수 값을 확인할 수 있습니다. 디버거를 사용하여 torch._C
로부터 임포트된 함수를 식별할 수 있습니다.
def my_function(x):
# ...
return torch.add(x, 1)
# 디버거 실행
pdb.run("my_function(torch.randn(4, 4))")
# 디버거에서 `torch._C` 함수 찾기
# (1) 변수 `x`와 `y`를 확인하여 `torch._C` 모듈에 속하는지 확인
# (2) `bt` 명령어를 사용하여 호출 스택을 확인하고 `torch._C` 모듈에 속하는 함수를 찾기
pdb
모듈은 기본적인 디버깅 기능만 제공합니다. 더 강력한 디버깅 기능을 원한다면 PyCharm 또는 Visual Studio Code와 같은 IDE를 사용하는 것이 좋습니다.
pytorch