torch.no_grad() vs torch.inference_mode()의 차이점| 항목 | torch.no_grad() | torch.inference_mode() |
|---|---|---|
| 주요 목적 | 그래디언트 추적을 비활성화 (학습 안함) | 추론 전용 최적화 (성능 극대화) |
| Autograd 비활성화 | ✅ | ✅ |
| View tracking 비활성화 | ❌ 유지됨 | ✅ 끔 |
| Version counter 증가 비활성화 | ❌ 증가함 | ✅ 안 함 |
| in-place 연산 허용 | ✅ 가능 | ❌ 에러 발생 (Inference Tensor에 한해) |
| 성능 최적화 수준 | 중간 (적절함) | 최대 성능 (배치 추론 등) |
| 사용 예 | 테스트 시 loss 없이 출력만 확인할 때 | production inference, benchmarking 등 |
torch.no_grad() 예시x = torch.randn(3, 3, requires_grad=True)
with torch.no_grad():
y = x * 2
print(y.requires_grad) # False
y[0][0] += 1 # ✅ 가능 (view tracking, version bump 있음)
torch.inference_mode() 예시x = torch.randn(3, 3)
with torch.inference_mode():
y = x * 2
print(y.requires_grad) # False
y[0][0] += 1 # ❌ RuntimeError: inplace update not allowed
💡
inference_mode는 내부적으로 생성된 텐서가 inference tensor로 간주되며,
inplace 연산, requires_grad 설정 변경, view 추적이 불가합니다.
torch.no_grad() → 실험/학습 도중 불필요한 gradient 추적을 끌 때 사용 torch.inference_mode() → 최대 성능이 필요한 추론 환경(Serving 등)에서 사용맞아요, 상속의 기본 개념은 자식 클래스가 부모 클래스의 기능을 "재사용"하거나 "확장"하는 거예요.
그리고 당신이 말한 super(무슨클래스, self).__init__() 또는 super().__init__() 는 부모 클래스의 초기화 메서드를 호출하는 방식입니다.
super().__init__() 이 정확히 뭔데?class Parent:
def __init__(self):
print("Parent init")
class Child(Parent):
def __init__(self):
super().__init__() # 이게 부모(Parent)의 __init__ 호출임
print("Child init")
이렇게 하면 실행 순서:
Parent init
Child init
즉, super()는 부모 클래스의 메서드를 "명시적으로" 호출하는 함수예요.
보통 __init__()에서 사용하는 이유는 부모 클래스가 처리하는 초기화 코드도 함께 실행되도록 하기 위해서예요.
super(무슨클래스, self) 말고 그냥 super() 만 쓰냐?super() 단독으로 써도 현재 클래스와 인스턴스를 자동으로 추론해서 동작합니다.super().__init__()은 super(CurrentClass, self).__init__()이랑 같은 의미임.| 문법 | 의미 |
|---|---|
super() | 부모 클래스의 메서드에 접근하는 내장 함수 |
super().__init__() | 부모 클래스의 생성자(초기화 함수)를 호출 |
super(ClassName, self).__init__() | Python 2 스타일 (Python 3에서는 생략 가능) |
| 사용 이유 | 자식 클래스에서 부모 클래스의 초기화 로직도 실행되게 하기 위해 |
만약 super() 호출 안 하면? → 부모 클래스의 __init__()이 실행되지 않아서 부모 필드가 초기화되지 않을 수 있어요.