LabHub

블로그

Python 3.13과 AI 시대의 부활 — GIL 제거, JIT, Typing, uv/ruff, PyTorch, Mojo까지 완전 정복 (2025)

"Python's success is not despite its simplicity. It's because of it." — Guido van Rossum (BDFL, 2018년 사임)

2008년 12월 3일, Python 3.0이 출시되었다. 그리고 Python 커뮤니티는 12년간 분열되었다. "2로 남을 것인가, 3으로 갈 것인가." 많은 이들이 Python의 종말을 예언했다. "Ruby on Rails에 웹을 내주고, Scala/Kotlin에 JVM을 내주고, Go에 서버를 내줬다"고.

그러나 2012년 AlexNet, 2015년 TensorFlow, 2018년 BERT, 2022년 ChatGPT... AI/ML 혁명이 Python을 왕좌로 올렸다. 2024년 GitHub Octoverse에서 Python이 JavaScript를 제치고 1위를 차지했다. 2025년 Stack Overflow에서 사용률 1위.

이 글은 "단순한 파이썬 스크립트"에서 "Python의 깊이와 미래"로 넘어가려는 사람을 위한 지도다.


1. Python의 기적적 재기 — 타임라인

1991 — 탄생

2008 — 2 vs 3 분열의 시작

2015 — Python 2 사망 공지

2020 — Python 2 EOL

2022 — ChatGPT

2024 — GitHub 1위

2025 — 현재


2. CPython 내부 — 어떻게 작동하는가

CPython = 기본 구현

실행 파이프라인

source.py
   (파싱)
AST
   (컴파일)
bytecode (.pyc)
   (실행)
ceval.c의 거대한 switch

ceval.c — 인터프리터의 심장

바이트코드 보기

import dis
def f(x):
    return x * 2 + 1

dis.dis(f)
  2           0 LOAD_FAST                0 (x)
              2 LOAD_CONST               1 (2)
              4 BINARY_MULTIPLY
              6 LOAD_CONST               2 (1)
              8 BINARY_ADD
             10 RETURN_VALUE

Reference Counting

GIL — Global Interpreter Lock

이것이 Python 성능 역사의 중심이다.


3. GIL — 30년의 축복과 저주

GIL이란

한 시점에 하나의 스레드만 Python 바이트코드를 실행할 수 있게 하는 락.

왜 존재하나

결과

장점:

단점:

우회 방법들

  1. multiprocessing — 프로세스 분리, 오버헤드 큼
  2. asyncio — I/O 집중에만
  3. C 확장 (NumPy, PyTorch) — GIL 해제하고 네이티브 실행
  4. Cython — C로 컴파일

30년의 "GIL 제거 시도 실패사"


4. PEP 703 — Free-Threaded Python (3.13)

Sam Gross의 nogil 포크

3.13 (2024년 10월)

3.14-3.15 — 점진 안정화

목표 — 2026-2027

싱글스레드 성능 비용

C extension 저자의 부담


5. Python이 갑자기 빨라진 이유 — Faster CPython (3.11+)

프로젝트 시작

3.11 — 평균 25%, 최대 60% 빠름

주요 최적화:

3.12 — 더 빠르게

3.13 — JIT + Free-Threaded

JIT의 원리 — Copy-and-patch


6. 타입 힌트의 진화

PEP 484 (2014) — 타입 힌트 도입

def greet(name: str) -> str:
    return f"안녕, {name}"

런타임에는 영향 없음 (주석에 가까움).

PEP 526 — 변수 타입 (2016)

age: int = 30
names: list[str] = []

PEP 585 (3.9) — 기본 제네릭

# 이전
from typing import List, Dict
def f(x: List[int]) -> Dict[str, int]: ...

# 3.9+
def f(x: list[int]) -> dict[str, int]: ...

PEP 604 (3.10) — Union 간편 문법

# 이전: Optional[str] 또는 Union[str, None]
# 3.10+:
def f(x: str | None): ...

TypedDict (3.8+)

from typing import TypedDict

class User(TypedDict):
    name: str
    age: int

u: User = {'name': '김', 'age': 30}

JSON 스키마처럼 딕셔너리에 타입 부여.

Protocol (3.8+) — 구조적 타이핑

from typing import Protocol

class Greetable(Protocol):
    def hello(self) -> str: ...

def greet(x: Greetable) -> None:
    print(x.hello())

# Kim은 Greetable을 상속하지 않아도 OK (구조적 타이핑)
class Kim:
    def hello(self) -> str: return "안녕"

greet(Kim())  # OK

Generic (3.12의 PEP 695)

# 3.12+ 간결한 문법
def first[T](items: list[T]) -> T:
    return items[0]

class Stack[T]:
    def push(self, item: T) -> None: ...

TypeGuard와 narrow (3.10+)

from typing import TypeGuard

def is_str_list(val: list) -> TypeGuard[list[str]]:
    return all(isinstance(x, str) for x in val)

def process(items: list):
    if is_str_list(items):
        for s in items: print(s.upper())  # str로 narrow됨

7. 타입 체커 전쟁 — mypy, pyright, pyrefly

mypy — 원조 (2012)

pyright — VSCode의 무기 (2019)

pyrefly (2025) — Meta의 Rust 체커

비교

측면mypypyrightpyrefly
구현 언어PythonTypeScriptRust
속도느림빠름매우 빠름
VSCode 통합플러그인네이티브(Pylance)작업 중
엄격성기본 완화엄격 옵션 많음pyright 유사
커뮤니티크다크다성장중

8. Astral의 Rust 혁명 — uv와 ruff

배경

2022년까지 Python 도구는 파편화:

Charlie Marsh의 Astral

ruff — 린터+포맷터

ruff format — Black 대체

uv — pip/poetry 대체 (2024)

# 프로젝트 초기화
uv init

# 의존성 추가 (pip install + pyproject.toml 업데이트)
uv add requests

# 의존성 설치
uv sync

# 스크립트 실행 (자동으로 venv 활성)
uv run python script.py

# Python 버전도 자동 관리 (pyenv 대체)
uv python install 3.13

충격적 속도

2025 채택


9. pytest와 현대 테스트

pytest — 사실상 표준

def test_add():
    assert add(2, 3) == 5

@pytest.fixture
def user():
    return User(name="Kim")

def test_greet(user):
    assert user.greet() == "안녕, Kim"

표준 unittest보다 훨씬 간결. Fixture, parametrize, hook이 강력.

pytest-xdist — 병렬 실행

pytest -n auto  # CPU 코어 수만큼

hypothesis — Property-based Testing

from hypothesis import given, strategies as st

@given(st.integers(), st.integers())
def test_add_commutative(a, b):
    assert add(a, b) == add(b, a)

Haskell QuickCheck 영향. 수백 개 케이스 자동 생성.

coverage.py

coverage run -m pytest
coverage report --fail-under=80

10. AI/ML 스택 — Python이 왕이 된 이유

NumPy (2006) — 행렬의 황제

Pandas (2008)

scikit-learn (2007)

TensorFlow (2015) vs PyTorch (2016)

PyTorch의 우아함

import torch
import torch.nn as nn

class MLP(nn.Module):
    def __init__(self):
        super().__init__()
        self.layers = nn.Sequential(
            nn.Linear(784, 256),
            nn.ReLU(),
            nn.Linear(256, 10),
        )
    
    def forward(self, x):
        return self.layers(x)

model = MLP()
optimizer = torch.optim.Adam(model.parameters())

JAX

HuggingFace Transformers

LangChain / LlamaIndex


11. 웹/서버 Python

Django (2005) — 배터리 포함 풀스택

Flask (2010) — 마이크로

FastAPI (2018) — 현대적 표준

from fastapi import FastAPI
from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int

app = FastAPI()

@app.post("/users")
async def create_user(user: User) -> User:
    return user

이 30줄로 OpenAPI 문서, 타입 검증, 비동기 서버가 완성.

Starlette + Uvicorn


12. 대안 인터프리터 — CPython 아닌 Python

PyPy

Mojo (2023)

GraalPython

Faster-CPython 팀


13. 현실의 Python 성능 최적화

1단계 — 프로파일링

import cProfile
cProfile.run('my_function()')

또는 py-spy, scalene 같은 현대 도구.

2단계 — 벡터화

# 느림
result = [x * 2 for x in huge_list]

# 빠름
import numpy as np
arr = np.array(huge_list)
result = arr * 2

3단계 — 네이티브 코드

4단계 — 멀티프로세싱 / asyncio

# CPU 바인딩
from multiprocessing import Pool
with Pool(8) as p:
    results = p.map(f, items)

# I/O 바인딩
import asyncio
results = await asyncio.gather(*[fetch(url) for url in urls])

5단계 — 프리 스레디드 (3.13+)

import threading
# GIL 없는 빌드에서는 진짜 병렬

14. 2025년 Python 생태계 맵

필수 도구

웹/API

데이터/ML

운영


15. 안티패턴 TOP 10

  1. pip install -r requirements.txt만으로 재현 — uv/poetry lock 써라
  2. global state 남발 — 테스트 지옥
  3. mutable default argdef f(x=[]) 금지, 공유됨
  4. except: 모든 에러 잡기 — 타입 명시
  5. list comprehension vs for의 과도 대비 — 가독성 우선
  6. type hint 없이 대규모 코드 — 장기 유지보수 어려움
  7. import * — 네임스페이스 오염
  8. synchronous requests를 FastAPI에서httpx.AsyncClient
  9. 설치 스크립트를 setup.py로pyproject.toml 표준
  10. Python 2 코드 유지 — 2020년 EOL, 마이그레이션

16. Python 체크리스트


마치며 — "뱀이 왕좌에 올랐다"

2012년 HackerNews에서 "Python is dead"라는 글이 주기적으로 올라왔다. 2025년, 같은 플랫폼에서 "Python이 너무 많은 곳에서 쓰인다"는 불평이 올라온다. 12년 만의 반전이다.

Python이 살아남은 이유는 단순하다: 읽기 쉽고, 배우기 쉽고, "거의" 뭐든 할 수 있다. AI 연구자가 새 아이디어를 3시간 만에 구현할 수 있어서, 주피터 노트북에서 실험한 코드를 그대로 프로덕션에 올릴 수 있어서, 수많은 라이브러리가 "import"만으로 작동해서.

그리고 2025년, 부족했던 마지막 조각이 채워지고 있다:

  1. 속도 — Faster CPython + JIT + Mojo
  2. 동시성 — PEP 703의 free-threaded Python
  3. 도구 UX — Astral의 uv/ruff Rust 혁명
  4. 타입 안전성 — pyrefly, pydantic v2
  5. 배포 — Docker + uv의 5초 이미지 빌드

"Python was never the best language. It was just the right language, at every moment it needed to be." — Luciano Ramalho (Fluent Python 저자)


다음 글 예고 — 현대 웹 성능의 과학 — Core Web Vitals, INP, RUM, Lighthouse까지

Python이 "어떻게 빨라지고 있나"라면, 웹 성능은 "왜 내 사이트가 느린가"에 답한다. 2024년부터 INP(Interaction to Next Paint)가 LCP와 함께 Core Web Vitals 3대 지표로 공식화되었다. 다음 글에서는:

"왜 느린가"에 과학적으로 답하는 여정.


"Python is syntactic sugar on top of numpy which is syntactic sugar on top of CUDA which is syntactic sugar on top of silicon. The whole AI industry runs on sugar." — Anonymous tweet (2024)

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다