"API 는 백 개 요청을 저글링할 수 있어. GPU 는 정확히 하나 돌릴 수 있고. 그건 다른 두 숫자고, 설계가 둘 다 존중해야 해."
자주 헷갈리는 두 종류의 동시성
async 서버는 많은 요청을 한꺼번에 받게 지어졌어 — 그게 반응형으로 유지하는 거야. 함정은 '많이 받기' 가 '많이 실행' 을 뜻해야 한다고 가정하는 거야. 대부분의 웹 작업엔 그래. GPU inference 엔 절대 안 돼: API 레이어는 행복하게 동시성 유지하고 실제 GPU 작업은 엄격히 한 번에 한 job 씩 돌아야 해. 이 둘을 뭉뚱그리는 게 반응형 서버가 load 하에 크래시난 서버로 변하는 길이야.
왜 두 inference 동시가 다시 OOM 인지
앞 lesson 을 떠올려: 단일 diffusion inference 는 진짜 peak 메모리 비용을 가져. 둘을 동시에 돌리면 그 peak 을 두 배 해. 유한한 디바이스에선, peak 메모리 두 배가 방금 고친 out-of-memory 크래시로 도로 가는 길이야. inference_mode 해법이 한 job 의 메모리를 경계 지었는데; 두 job 동시 실행이 그걸 다시 경계 풀어. GPU 의 동시성이 다른 모든 데의 메모리 규율을 무효화해.
하나의 semaphore
메커니즘은 작아: 한 번에 정확히 하나의 holder 를 허용하는 동시성 게이트, adapter 의 GPU 섹션 둘레에 감싸짐. job queue 는 여전히 모든 걸 받고 모든 비-GPU 작업을 동시에 돌려 — 검증, 큐잉, 응답 스트리밍. 근데 job 이 실제 inference 에 닿으면, 단일 permit 을 획득해야 해. 둘째 job 은 첫째가 풀 때까지 그 게이트에서 기다려. API 는 절대 안 막히고; GPU 섹션만 직렬화돼.
그냥 더 큰 머신은 왜 안 돼?
메모리 더 사서 더 많은 동시 inference 를 돌릴 수 있어 — 근데 그건 천장을 옮길 뿐, 제거 안 해. 메모리가 아무리 많아도, 어떤 수의 동시 inference 가 그걸 초과하고, 게이트 없이는 그 수를 어렵게, 프로덕션에서 찾아. semaphore 가 엔진을 어떤 메모리 크기에서든 올바르게 만들어: 디바이스가 얼마나 크든, 디바이스가 담을 수 있는 것보다 많은 GPU 작업을 절대 안 돌리려 해. 올바름이 capacity 를 이겨.