스크립트
00:00:00그럼 다들 좋은 오후입니다. 제 이름은 하샬 진이고 옆에 분은 탄미샤입니다. 저희는
00:00:21LLM 추론에 관한 이 두 시간짜리 워크숍에 여러분을 환영하고자 합니다.
00:00:26이 워크숍의 목표는 제1원칙부터 이 도메인을 이해하고,
00:00:33더 깊이 파고들어 업계 전반에서 어떤 일이 일어나고 있는지
00:00:39파악하는 것입니다. 저희에 대해 간단히 소개해 드리자면, 저는 오디블의 시니어 소프트웨어 엔지니어로
00:00:47지난 5년 동안 ML/AI 데이터 플랫폼을 구축해 왔으며,
00:00:53부수적으로 LLM 추론에 관한 오픈소스 핸드북을 집필해 왔습니다. 그리고
00:00:59탄마이는 시안스 뱅크 코퍼레이션의 시니어 양적 모델러입니다. 그는
00:01:06최근 박사 학위를 마치고 에이전트 검증기와 세계 모델 분야에서 활발히 연구를
00:01:12수행해 왔습니다. 자, 가볍게 거수 부탁드립니다. LLM 추론이 완전히 처음이신 분은 누구인가요?
00:01:24네, 좋습니다. 그럼 이 모델들을 프로덕션에 배포해 보신 분은요? 튜닝도 해보고,
00:01:33프로덕션 트래픽을 서빙해 보신 분들이요. 네, 좋습니다. 그렇다면 이
00:01:42워크숍은 초급 및 중급 수준을 대상으로 합니다. 그리고 모든
00:01:48슬라이드와 실습 코드는 저장소에 있으며 곧 공유해 드리겠습니다. 워크숍의 간략한
00:01:56아젠다는 다음과 같습니다. 먼저 문제 정의부터 시작하겠습니다. LLM 추론과 관련된
00:02:01몇 가지 고충점을 이해해 보려 합니다. 그런 다음 그러한 고충점의 원인을 파악하고
00:02:08그로부터 기초를 다질 것입니다. 이어서 우리가 수행하는 두 가지 종류의
00:02:14최적화, 즉 모델 최적화와 서빙
00:02:19최적화에 대해 깊이 알아봅니다. 그런 다음 프로덕션에 LLM 추론 솔루션을 배포하기 위해
00:02:25사용할 수 있는 다양한 서빙 엔진에 대해 배우고, 몇 가지 벤치마크와
00:02:32어떤 엔진을 사용해야 할지 보여주는 의사결정 차트를 소개하겠습니다.
00:02:39좋습니다. 고충점을 이해하려면 먼저 LLM 추론이란 무엇인지 알아야 합니다. 그래서
00:02:47아마 우리 중 많은 분들이 이미 알고 계실 것입니다. 하지만 비디오, 오디오 생성, 텍스트 분석, 의료 보고서 분석 등
00:02:55AI에게 시키는 모든 작업,
00:03:02세금 고지서 분석 등이 모두 LLM 추론입니다. 그리고 이 시장은 현재 약 230억 달러 규모입니다.
00:03:12세미애널리시스(SemiAnalysis)는 최근 구글 검색 쿼리를 LLM으로 모델링하려면 360억 달러 규모의 자금 유출이 필요하다고 밝혔습니다.
00:03:25그리고 검색 사업을 수익성 있게 유지하려면 쿼리당 비용이 0.5센트 미만이어야 합니다.
00:03:33반면 비즈니스 인사이더는 AI가 제대로 작동해야 하며 모든 사람이 토큰 사용량을 감사하고 예산을 책정하기 시작해야 한다고 언급했습니다.
00:03:43이 모든 일이 왜 일어날까요? 하드웨어가 한정되어 있고, 연산 비용이 비싸며, 추론 비용이 비싸기 때문입니다.
00:03:50그리고 AI 사용이 점점 늘어남에 따라 이 추론 비용은 갈수록 치솟고 있습니다.
00:04:03이 통계는 오픈AI의 오래된 통계이지만 여전히 유효합니다.
00:04:11GPT-3의 훈련 비용을 살펴보면 대략 460만 달러 정도였습니다. 일회성 비용이었죠.
00:04:19하지만 추론 비용을 보면, 이는 유입되는 모든 사용자, 유입되는 모든 토큰, AI에서 시작되는 모든 세션에 따라 규모가 커지는 운영 비용이기 때문에 반복적인 비용입니다.
00:04:36이에 대응하는 방법은 기본적으로 두 가지뿐인데, 한 가지 방법은 토큰 사용량을 줄이는 것입니다.
00:04:47대안은 고객과 자신을 위해 추론 서비스 제공업체로서 추론 솔루션을 최적화하려고 노력하는 것입니다.
00:04:58그래서 우리는 매 순간 수많은 새로운 솔루션이 나오는 것을 목격해 왔습니다.
00:05:06따라서 앞으로 출시될 그 어떤 기술이든 이해하고 평가하는 데 도움이 될 기반을 다져보자는 아이디어입니다.
00:05:18그럼 시작하기 위해, 추론과 관련된 다양한 고충점이 무엇인지 간단한 데모를 진행하겠습니다.
00:05:28이것은 저장소입니다.
00:05:31클론할 수도 있고 GitHub에서 열어볼 수도 있습니다.
00:05:36이름은 'LLM Inference at Scale'입니다.
00:05:39배경을 조금 말씀드리자면, 4개월 전에 저는 LLM 추론에 대해 아무것도 몰랐을 때 공부를 시작했습니다.
00:05:46많은 리소스들이 흩어져 있다는 것을 알게 되었죠.
00:05:49그래서 사람들에게 도움이 되도록 그 모든 것을 한곳에 모으기 시작했습니다.
00:05:55네, 그럼 실제로 이 슬라이드 쇼 모드에서 나와서 확장 모드로 들어가 보겠습니다.
00:06:11네, 이 저장소에서 README 파일을 보면 슬라이드 링크가 있습니다.
00:06:27이 폴더에는 PPTX와 벤치마크 보고서가 들어 있습니다.
00:06:34언제든지 다운로드할 수 있으며, 데모를 위해 몇 개의 주피터 노트북을 준비했습니다.
00:06:43Google Colab의 대안인 Molab과 협력하여 무료 RTX 6000 GPU를 제공하고 있습니다.
00:06:54따라서 100GB RAM GPU이며, 쉽게 실험해 볼 수 있도록 이러한 노트북을 이미 설정해 두었고 모든 자산과 설정이 미리 준비되어 있습니다.
00:07:09그럼 간단한 데모 A부터 시작하겠습니다.
00:07:16아마도, 잠시만요.
00:07:31네, 추론을 할 때는 특정 모델로 추론을 수행해야 하잖아요?
00:07:40그래서 워크숍을 위해 간단한 Mistral 7B 모델을 사용하고 있습니다.
00:07:45크기가 약 15GB인 작은 모델입니다.
00:07:49따라서 이를 GPU에 로드할 것입니다.
00:07:53그리고 몇 가지 GPU 통계도 살펴볼 것입니다.
00:07:58보시다시피 우리는 6000 블랙웰(Blackwell)에서 작업하고 있습니다.
00:08:01컨퍼런스 와이파이를 신뢰하지 않기 때문에 제가 셀을 실행하지 않는다고 생각하실 수도 있습니다.
00:08:08그래서 이전에 실행했던 결과를 바탕으로 살펴보겠습니다.
00:08:18네, 102GB짜리 GPU가 있습니다.
00:08:22자, LLM 추론을 수행할 때 가장 먼저 떠오르는 것은 메모리 소비량이 어떻게 되는가입니다.
00:08:31이 모델을 로드하고 보니 대략 15GB를 차지합니다.
00:08:37따라서 대략 87.5GB가 남습니다.
00:08:40이제 여기서 추론을 수행해 보면, 입력하는 데이터의 수가 많을수록 더 많은 메모리가 필요하다는 것을 알 수 있습니다.
00:08:52서서히 증가하지만 여전히 증가하고 있습니다.
00:08:56컨텍스트 길이가 4,000, 16,000, 또는 32,000 토큰 정도라고 상상해 보세요.
00:09:03그럼 이 메모리가 정말 크게 늘어나서 실제로 메모리 부족(OOM) 문제가 발생할 수 있습니다.
00:09:12따라서 이것이 첫 번째 문제, 즉 토큰 증가에 따라 메모리가 증가하는 문제입니다.
00:09:18간단한 시각화 형태로 보면 다음과 같습니다.
00:09:24두 번째로 보게 될 문제는 첫 토큰 생성 시간(TTFT)이 매우 매우 느리다는 점입니다.
00:09:32TTFT라는 지표로 측정합니다.
00:09:35줄임말입니다.
00:09:37입력 크기에 따라 TTFT를 측정해 보면 컨텍스트가 길어질수록 이 TTFT가 느려지는 것을 볼 수 있습니다.
00:09:52자, 이제 두 가지 문제가 있습니다.
00:09:54토큰 크기에 따라 메모리가 증가합니다.
00:09:56토큰 크기에 따라 TTFT가 증가합니다.
00:09:59죄송합니다, 토큰 크기가 아니라 컨텍스트 크기입니다.
00:10:07그리고 세 번째는 처리량(Throughput)입니다.
00:10:09처리량은 초당 몇 개의 토큰을 서빙할 수 있는가입니다.
00:10:13그리고 초당 몇 명의 사용자를 지원할 수 있는가입니다.
00:10:16로컬 시스템에 아주 아주 순수한(vanilla) 구현을 적용하면 매우 순차적일 것입니다.
00:10:24따라서 요청 5개를 보내면 그 5개의 요청이 병렬이 아니라 순차적으로 처리됩니다.
00:10:31그래서 사용자 수가 많아지면 요청을 처리하는 데 더 오랜 시간이 걸리게 됩니다.
00:10:40이러한 세 가지 문제가 있습니다.
00:10:43네 번째 문제도 있습니다.
00:10:44여기서는 설명하지 않았습니다.
00:10:45아마 진행하면서 그 직관을 쌓아가게 될 것입니다.
00:10:48하지만 기억해야 할 것은 이 세 가지 문제, 즉 메모리, TTFT, 그리고 처리량입니다.
00:10:55좋습니다.
00:10:56다시 슬라이드로 돌아가겠습니다.
00:11:02알겠습니다.
00:11:03완벽합니다.
00:11:04이 화면이어야 합니다.
00:11:17보이나요?
00:11:18네.
00:11:19보입니다.
00:11:20보입니다.
00:11:21네.
00:11:22보입니다.
00:11:23보입니다.
00:11:24보입니다.
00:11:25네.
00:11:26보입니다.
00:11:27보입니다.
00:11:28네.
00:11:29보입니다.
00:11:30네.
00:11:31보입니다.
00:11:32네.
00:11:33보입니다.
00:11:34네.
00:11:35보입니다.
00:11:36보입니다.
00:11:37네.
00:11:38보입니다.
00:11:39네.
00:11:40보입니다.
00:11:41네.
00:11:42보입니다.
00:11:43네.
00:11:44보입니다.
00:11:45네.
00:11:46네.
00:11:47따라서 해당 저장소 내에서 워크숍 폴더를 보면 README가 있고, 그 README에
00:11:55모든 링크, 슬라이드, 데모가 있습니다.
00:12:01잘 되나요?
00:12:06알겠습니다.
00:12:07완벽합니다.
00:12:09좋습니다.
00:12:10완벽합니다.
00:12:16자,
00:12:17이제 기초부터 차근차근 살펴보겠습니다.
00:12:19이러한 고충점의 이면에 있는 원인이 무엇인지 이해해 봅시다.
00:12:25그러기 위해서 이 추론 파이프라인을 살펴봐야 합니다.
00:12:32입력 텍스트가 있다고 가정해 봅시다.
00:12:35이 텍스트는 임의의 수의 단어를 포함할 수 있습니다.
00:12:38우리는 그 단어들을 토큰으로 변환합니다.
00:12:41따라서 간단히 단어 하나가 토큰 하나와 같다고 가정할 수 있죠.
00:12:46그런 다음 이를 임베딩으로 변환하고 트랜스포머에 전달합니다.
00:12:53트랜스포머 레이어가 32개 있지만, 이는 미스트랄 7B에만 해당하는 특성입니다.
00:12:58모델마다 레이어의 종류와 개수가 다르죠.
00:13:01그리고 새로운 토큰을 생성하게 됩니다.
00:13:04그 토큰은 기본적으로 다시 입력으로 들어가고,
00:13:06또 다른 토큰을 생성하는 과정이 계속 반복됩니다.
00:13:09이 전체 파이프라인에서 연산의 약 95%가 이 트랜스포머 레이어에 의해 소모된다는 것을 알 수 있습니다.
00:13:18따라서 이 트랜스포머 레이어 내부에서 무슨 일이 일어나는지 살펴볼 가치가 있습니다.
00:13:24트랜스포머 레이어 안에는 더 많은 하위 레이어들이 존재합니다.
00:13:28정규화 레이어가 있고,
00:13:30어텐션 레이어가 있으며,
00:13:32피드 포워드 레이어 등이 있습니다.
00:13:35그중에서도 어텐션 레이어가 매우 유명해졌다고 생각합니다.
00:13:40어텐션이 전부라는 논문의 저자들처럼 말이죠.
00:13:42다들 잘 알고 계실 겁니다.
00:13:44어텐션은 연산량이 가장 많은 레이어입니다.
00:13:48따라서 우리는 그 어텐션 레이어 내부에서 무슨 일이 일어나는지 이해해야 합니다.
00:13:53어텐션은 과연 어떤 역할을 할까요?
00:13:56입력 텍스트가 있을 때, 모든 이전 토큰들에 대한 각 토큰의 어텐션 점수를 찾아내야 합니다.
00:14:05이를 위해 각 토큰을 키, 쿼리, 그리고 밸류 공간으로 각각 투영해야 합니다.
00:14:14더 알기 쉽게 간단히 설명하자면 이렇습니다.
00:14:20토큰이 10개라면, 10개의 서로 다른 쿼리, 키, 밸류 벡터가 필요합니다.
00:14:26토큰이 100개라면 100개의 키와 밸류 벡터가 필요하겠죠.
00:14:31토큰이 1000개라면 1000개의 키 밸류 벡터가 필요합니다.
00:14:35즉, 입력 크기가 커질수록 키와 밸류 벡터의 수도 함께 증가합니다.
00:14:45미스트랄 7B의 토큰당 KV 크기를 계산해보면 131바이트 정도가 됩니다.
00:14:54K와 V라는 두 개의 벡터가 존재하기 때문입니다.
00:14:59크기를 곱해 계산해야 하죠.
00:15:02벡터 하나는 128차원입니다.
00:15:04이를 32개의 트랜스포머 레이어 수만큼 곱해야 합니다.
00:15:08그런 다음 KV 헤드 수와도 곱해줘야 하죠.
00:15:11미스트랄 7B의 KV 헤드 수는 그렇습니다.
00:15:1532개와는 다르죠. 다른 방식의 어텐션 메커니즘을 사용하기 때문인데, 이 부분은 확실히 짚고 넘어가겠습니다.
00:15:23아무튼 토큰당 KV 크기는 대략 131 정도 됩니다.
00:15:30이제 4K 컨텍스트를 사용한다고 상상해 보면, 그 크기는 약 0.5GB가 됩니다.
00:15:3716K 컨텍스트를 사용하면 크기가 2.1GB로 늘어납니다.
00:15:42여기에 사용자 수를 곱해 보세요.
00:15:45여러 사용자를 동시에 서비스한다고 가정해 봅시다.
00:15:494K 컨텍스트와 80명의 사용자가 있다면 GPU 내에서 42GB를 차지할 수 있습니다.
00:15:58만약 GPU 용량이 24GB에 불과하다면 이미 메모리가 부족해지기 시작하죠.
00:16:04따라서 그만큼 많은 컨텍스트로 많은 사용자를 서비스할 수 없게 됩니다.
00:16:11이를 시각적으로 확인하기 위해 GPU 메모리를 살펴보겠습니다.
00:16:14GPU 메모리에는 꽤 고정되어 있는 모델 가중치가 있습니다.
00:16:19이것은 사전 학습된 가중치입니다.
00:16:21또한 고정된 오버헤드도 존재합니다.
00:16:24오버헤드 역시 변하기는 하지만 그렇게 크게 변하지는 않습니다.
00:16:29전체적으로 고정되어 있다고 볼 수 있죠.
00:16:32그리고 남은 메모리가 있습니다.
00:16:35이 남은 메모리가 바로 KV 메모리, 즉 키와 밸류 벡터에 의해 사용되는 공간입니다.
00:16:41사용자가 한 명 있다고 가정해 봅시다.
00:16:46남아 있는 전체 80GB 메모리에 들어맞을 만큼의 키와 밸류 벡터, 혹은 그만큼의 토큰만 서비스할 수 있습니다.
00:17:00간단한 데모를 통해서도 이를 보여드릴 수 있습니다.
00:17:07좋습니다.
00:17:08좋습니다.
00:17:08실제로 실행할 수 있는지 한번 확인해 보겠습니다.
00:17:14좋습니다.
00:17:15실제로 실행할 수 있는지 확인해 볼게요.
00:17:15이게 도대체 어디 있죠?
00:17:15좋습니다.
00:17:16실제로 실행할 수 있는지 확인해 보겠습니다.
00:17:21이게 도대체 어디 있는 거지?
00:17:22좋습니다.
00:17:23좋습니다.
00:17:24네.
00:17:25네.
00:17:25보시다시피... 실제로 실행할 수 있는지 확인해 보겠습니다.
00:17:31실제로 실행할 수 있는지 확인해 보겠습니다.
00:17:33한번 실행해 보죠.
00:17:34한번 실행해 보겠습니다.
00:17:35한번 실행해 보죠.
00:17:36한번 실행해 보겠습니다.
00:17:37좋습니다.
00:17:38네.
00:17:39보시다시피 GPU가 연결되어 있습니다.
00:17:43좋습니다.
00:17:44네.
00:17:45보시다시피 GPU가 연결되어 있죠.
00:17:56여기서는 우리가 세운 수식과 직관을 바탕으로 메모리를 확인해 보려고 합니다.
00:18:13우리가 구축한 직관 말이죠.
00:18:14모델 메모리의 경우, 예를 들어 70억 개의 파라미터가 있고
00:18:1916비트 정밀도를 사용한다고 가정해 봅시다.
00:18:20총 메모리는 14.6GB가 나옵니다.
00:18:23수식을 통해 기본적으로 이를 검증할 수 있습니다.
00:18:27그 모든 수식을 계산해보면 14.6GB가 나오죠.
00:18:33이제 KV와 KV 크기에 대해 이야기해 보겠습니다.
00:18:37이 KV 크기는 토큰당 131 정도입니다.
00:18:42수식을 계산하고 이를 시각화해보면 됩니다.
00:18:47아, 물론입니다.
00:18:52잠시만요.
00:18:53좋습니다.
00:18:54그럼 이를 시각화해 보겠습니다.
00:19:07좋습니다.
00:19:10좋습니다.
00:19:11네.
00:19:12이것이 바로 메모리 차트입니다.
00:19:15보시다시피 컨텍스트가 증가할수록 메모리도 계속 증가합니다.
00:19:21그리고 또 한 가지 깨달아야 할 점은 사용자가 늘어날수록 메모리도 함께 증가한다는 것입니다.
00:19:28따라서 하나의 GPU에서 160명의 사용자를 서비스하고 싶다면, 지원할 수 있는
00:19:37컨텍스트 길이는 더 짧아질 수밖에 없습니다.
00:19:40결국 제공할 수 있는 컨텍스트 길이와, 여러 사용자 또는 동시 사용자를
00:19:47하나의 GPU에 수용함으로써 절약할 수 있는 비용 사이에는 항상 상충 관계가 존재합니다.
00:19:54따라서 항상 이러한 트레이드오프를 고려해야 합니다.
00:19:57이 내용은 몇 가지 슬라이드를 더 보면서 살펴보겠습니다.
00:20:06다시 말씀해 주시겠어요?
00:20:10죄송합니다.
00:20:11목소리가 잘 안 들립니다.
00:20:12컨텍스트 길이가 다른 별도의 풀을 두어 적절한 메모리를 서비스할 수 있도록
00:20:25고려하시나요?
00:20:26네.
00:20:27좋습니다.
00:20:28좋습니다.
00:20:29알겠습니다.
00:20:30좋습니다.
00:20:31그럼 다시 돌아가서요.
00:20:32아까 메모리 이야기였습니다.
00:20:33컨텍스트 길이를 늘렸을 때 첫 번째 토큰 생성 시간이 왜 더 느려졌는지 이해해야 합니다.
00:20:53길이 말이죠.
00:20:54이를 위해 추론의 두 가지 단계를 이해할 필요가 있습니다.
00:20:58그 단계는 바로 프리필(pre-fill) 단계와 디코드(decode) 단계입니다.
00:21:01관련된 글들을 많이 보셨겠지만, 여기서 다시 한번 설명해 드리려고 합니다.
00:21:06많은 입력 토큰을 보낼 때 우리가 하고 싶은 것은, 앞서 언급했던 모든 토큰에 대한 키와 밸류 벡터를 구축하는 것입니다.
00:21:20그런 다음 이전 토큰들에 대한 각 토큰의 어텐션 점수를 계산해야 합니다.
00:21:27이러한 모든 작업은 행렬 연산이 매우매우 많이 들어갑니다.
00:21:31연산 부하가 엄청나게 큰 작업이죠.
00:21:34우리도 잘 알듯이 GPU는 무거운 연산 워크로드에 매우 적합합니다.
00:21:41그래서 프리필 단계를 연산 집약적(compute-bound)이라고 부릅니다.
00:21:46완료되는 데 어느 정도 시간이 걸릴 수밖에 없습니다.
00:21:49따라서 이 단계가 완료되는 데 걸리는 시간이 바로 첫 번째 토큰 생성 시간(TTFT)이 됩니다.
00:21:55입력 토큰이 더 많다면, 더 많은 키 밸류 벡터를 생성해야 합니다.
00:22:02훨씬 더 많은 어텐션 연산을 수행해야 하죠.
00:22:05그로 인해 TTFT가 점점 더 느려지게 됩니다.
00:22:12반면에 토큰을 하나 생성한 후에는, 다른 토큰들을 생성하기 위해 이를 계속해서 순차적으로 반복해야 합니다.
00:22:20하지만 그 과정에서 매번 이전의 모든 토큰에 대한 키 및 값 벡터를 구축해야 하는데, 이는 프리필 단계와 같습니다.
00:22:30프리필 단계에서도 키 값 벡터를 구축했던 것처럼 여기서도 마찬가지입니다.
00:22:34하지만 디코드 단계에서는 새로운 토큰에 대한 어텐션 연산만 수행합니다.
00:22:40그렇기 때문에 연산 비중이 훨씬 더 적습니다.
00:22:45또한 이를 메모리 바운드라고도 부릅니다.
00:22:48왜 메모리 바운드라고 부르는지 곧 살펴보겠습니다.
00:22:54따라서 전형적인 타임라인에서는 프리필과 디코드 단계를 이와 같이 볼 수 있습니다.
00:22:59프리필이 소요하는 시간이 곧 첫 번째 토큰 생성 시간(TTFT)입니다.
00:23:03그리고 각 디코드 단계가 소요하는 시간은 기본적으로 토큰 간 지연 시간(inter-token latency)이 됩니다.
00:23:12이것이 여러분이 신경 써야 할 네 번째 지표입니다.
00:23:18디코드 단계에서 소요되는 시간이 얼마나 되는가 하는 점입니다.
00:23:21좋습니다.
00:23:22좋습니다.
00:23:23좋습니다.
00:23:24그렇다면 디코드 단계는 왜, 무엇 때문에 시간이 오래 걸릴까요?
00:23:34그리고 왜 메모리 바운드 연산이라고 불리는 걸까요?
00:23:38그 이유를 이해해 봅시다.
00:23:40이를 이해하기 위해 GPU에서 행렬 연산이 개략적으로 어떻게 작동하는지 살펴볼 필요가 있습니다.
00:23:47GPU에는 두 가지 종류의 메모리가 있습니다.
00:23:50고대역폭 메모리(HBM)가 있습니다.
00:23:52그리고 공유 메모리가 있습니다.
00:23:55고대역폭 메모리는 용량은 더 크지만 대역폭은 더 낮습니다.
00:24:01대역폭이 낮다는 것은 거기서 데이터를 전송하는 속도가 더 느리다는 뜻입니다.
00:24:06공유 메모리와 비교했을 때 그렇습니다. 공유 메모리는 용량은 더 작지만 대역폭이 매우 매우 높습니다.
00:24:13즉, 데이터를 안팎으로 매우 빠르게 전송할 수 있다는 뜻입니다.
00:24:19따라서 행렬 연산을 수행해야 할 때는 고대역폭 메모리에서 데이터를 청크 단위로 가져와야 합니다.
00:24:27이를 공유 메모리에 올려야 합니다.
00:24:30그리고 연산을 수행합니다.
00:24:32결과를 다시 고대역폭 메모리에 기록합니다.
00:24:38프리필 단계에서는 이 작업을 수행해야 할 때, 이 행렬 연산을 단 한 번만 수행하면 됩니다.
00:24:46하지만 디코드 단계에서는 모든 토큰을 하나씩 순차적으로 생성하기 때문에 이 행렬 연산을 계속해서 반복해야 합니다.
00:24:59그렇기 때문에 디코드 속도가 얼마나 빠른지는 중요하지 않습니다. 이제 고대역폭 메모리에서 공유 메모리로 데이터를 특정 속도로만 전송할 수 있기 때문입니다.
00:25:14고대역폭 메모리의 대역폭 속도에 제한을 받기 때문입니다.
00:25:18결과적으로 이것이 토큰 생성의 상한선을 결정하게 됩니다. 즉, 디코드 단계에서 실제로 토큰을 어느 정도의 속도로 생성할 수 있는지가 결정되는 것입니다.
00:25:32이를 루프라인 플롯(roofline plot)에서 살펴보면, 메모리 바운드라고 불리는 왼쪽 영역이 존재합니다.
00:25:42수학적으로 이는 연산 강도(arithmetic intensity)에 의해 좌우됩니다.
00:25:47연산 강도란 전송되는 데이터 1바이트당 수행하는 부동소수점 연산의 횟수를 의미합니다.
00:25:55따라서 디코드 단계의 경우, 이전 모든 토큰의 키 및 값 벡터, 그리고 모델 가중치와 같은 많은 데이터를 전송해야 하므로,
00:26:08단 하나의 토큰에 대해서만 어텐션 연산을 수행하기 때문에 연산량은 상대적으로 적습니다.
00:26:13그래서 연산 강도가 매우 낮습니다.
00:26:18하지만 프리필 단계에서는 데이터를 한 번 전송한 다음, 이러한 무거운 연산을 수행하게 됩니다.
00:26:27따라서 연산 강도가 매우 높습니다.
00:26:30이제 수학적 관점에서 왜 프리필의 연산 강도가 디코드에 비해 매우 높은지 이해하셨을 겁니다.
00:26:44좋습니다.
00:26:46이것은 또 다른 작고 간단한 데모입니다.
00:26:51좋습니다.
00:26:52매번 제가 해야 하는.
00:26:53좋습니다.
00:26:54좋습니다.
00:26:55좋습니다.
00:26:56이미 준비되었기를 바랍니다.
00:26:58그렇습니다.
00:26:59다시 모델을 로드하고 있습니다.
00:27:04자, 이것은 프리필 비용에 대한 내용입니다.
00:27:09따라서 우리가 기본적으로 하는 일은 입력 텍스트를 가져와서 프리필 단계와 그것이 소요하는 시간을 생성하려고 시도하는 것입니다.
00:27:22입력 토큰의 크기를 늘림에 따라 이 프리필 시간도 증가하는 것을 볼 수 있습니다.
00:27:28이것이 바로 TTFT가 증가하는 이유이며, 여러분도 잘 아실 겁니다.
00:27:33그리고 디코드 시간에 대해서도 마찬가지입니다.
00:27:36디코드 시간은 평균적으로 거의 동일하게 유지됩니다.
00:27:41따라서 콜드 스타트를 무시한다고 가정하면, 디코드 시간은 대략 평균선 주위에 위치합니다.
00:27:50그렇지만 여전히 입력 크기에 의해 영향을 받습니다.
00:27:57완전히 일정한 시간이 소요되는 것은 아닙니다.
00:28:00이전 모든 토큰에 대한 키 및 값 벡터를 여전히 메모리에서 가져와야 하기 때문입니다.
00:28:07따라서 디코드 단계에서도 시간이 소소하게 증가하는 것을 여전히 확인할 수 있습니다.
00:28:15그리고 이것이 전형적인 루프라인 플롯입니다.
00:28:20좋습니다.
00:28:22좋습니다.
00:28:23프레젠테이션.
00:28:24좋습니다.
00:28:25좋습니다.
00:28:26좋습니다.
00:28:27자, 이제 처리량(throughput) 측면에 대해 이해해 보도록 하겠습니다.
00:28:43실제로 몇 명의 사용자에게 서비스를 제공할 수 있는지 이해하고자 하는 것입니다.
00:28:48앞서 키 및 값 벡터가 커질 수 있도록 비워져 있는 메모리가 있다는 것을 GPU 메모리 다이어그램을 통해 보았다고 생각합니다.
00:28:56좋습니다.
00:28:57단 한 명의 사용자만 있다고 가정해 봅시다.
00:29:01지원할 수 있는 총 KV 크기는 얼마일까요?
00:29:09이는 컨텍스트 제한에 의해 정의됩니다.
00:29:11지원할 수 있는 최대 사용자 수는 GPU의 가용 메모리, 즉 GPU에서 사용 가능한 메모리를 사용자당 키 및 값 크기로 나눈 값입니다.
00:29:25그렇게 계산하면 동시 사용자 수가 도출됩니다.
00:29:32자, GPU가 고정되어 있고 모델이 고정되어 있어서 토큰당 KV 크기도 고정되어 있다고 가정해 보겠습니다.
00:29:46여기서 남은 차원은 컨텍스트와 동시 사용자 수, 이 두 가지뿐입니다.
00:29:53더 많은 동시 사용자에게 서비스를 제공하려면 컨텍스트 길이를 줄여야 합니다.
00:29:57컨텍스트 길이를 줄이면 품질에 영향을 줄 수 있습니다.
00:30:02결국 이것이 우리가 현재 트레이드오프를 하고 있는 두 가지 차원입니다.
00:30:09그렇다면 실제로 최대 동시 사용자 수만큼 서비스를 제공할 수 있을까요?
00:30:17이상적인 세계라면 아마 아닐 것입니다. 모든 비즈니스에는 충족해야 하는 지연 시간 서비스 수준 목표(SLO)가 있기 때문입니다.
00:30:27따라서 앞서 디코드 단계에서 말씀드렸듯이, 입력이 더 많아지면 디코드 시간도 여전히 증가합니다.
00:30:37사용자가 더 많아져도 이 시간은 증가합니다.
00:30:40결과적으로 배치 크기가 더 커지면 토큰 간 지연 시간도 영향을 받게 됩니다.
00:30:51또한 TTFT도 영향을 받습니다.
00:30:53이제 여러분이 신경 써야 할 세 번째 차원이 생겼는데, 바로 지연 시간입니다.
00:30:58가지고 있는 세 가지 차원은 품질, 지연 시간, 그리고 처리량입니다.
00:31:04결국 이들 사이에서 선택을 해야 하는 트레이드오프 삼각형이 만들어집니다.
00:31:11따라서 프리미엄 챗 애플리케이션의 경우, 품질을 확실히 우선시하고 싶을 것이며 지연 시간 또한 우선시하고 싶을 것입니다.
00:31:21사용자가 무한정 기다리게 하고 싶지는 않겠지만, 긴 지연 시간은 어느 정도 감수하려 할 것입니다.
00:31:30GPU에서 지원할 수 있는 사용자 수를 항상 희생하면서, 더 고객 집착적인 자세로 그 비용을 감수할 수 있습니다.
00:31:39그리고 에이전트, 죄송합니다. 비동기 에이전트 워크로드의 경우, 품질과 처리량을 확실하게 우선시하고 싶을 것입니다.
00:31:53이러한 작업들은 장시간 실행되는 작업이기 때문입니다.
00:31:56그리고 매우 높은 품질을 유지하면서 가능한 한 많은 동시 작업을 처리하고 싶을 것입니다.
00:32:06그리고 종종 우리는 '그래, GPU가 아주 비싼 GPU라면 우리에게 적합하지 않을지도 몰라'라고 생각하곤 합니다.
00:32:19하지만 알고 보면 그것이 실제로 백만 토큰당 가장 낮은 비용을 제공할 수도 있습니다.
00:32:27하지만 원하는 최대 사용자 수에 대한 계산을 정말 믿어야 하며, 이러한 추정치를 정확하게 수행해야 합니다.
00:32:40그래서 저희는, 잠깐만요, 아주 좋습니다.
00:32:55용량 계산기와 관련해서는, 제가 익숙했기 때문에 코랩(Colab) 링크가 있습니다.
00:33:01전체 위젯 라이브러리에서 마이그레이션을 해야 했는데 시간이 없었습니다.
00:33:16그래서 게으르게도 그냥 코랩을 선택했습니다.
00:33:20제 연구실에 사과드립니다.
00:33:23그래서 제 VRAM이 연결되어 있습니다.
00:33:34좋습니다.
00:33:45아마도 와이파이 문제겠죠.
00:33:46알겠습니다, 좋습니다.
00:34:02여기서 우리가 한 일은 여러 GPU를 VRAM, 대역폭, 부동소수점 연산 성능, 시간당 비용과 함께 정리해 둔 것입니다.
00:34:11그런 다음 이와 같은 간단한 용량 계산기를 만들었습니다.
00:34:19이것은 일종의 KV 시각화 도구로, 토큰 수를 늘리면 KV 크기가 증가하는 것을 볼 수 있습니다.
00:34:29그리고 사용자 수를 늘리면 크기가 훨씬 더 빠른 속도로 증가합니다.
00:34:37그런 다음, 이 용량 계산기를 실행해 보겠습니다.
00:34:47여기 선택한 70억(7B) 파라미터 모델 같은 모델이 있습니다.
00:34:56정밀도를 FP16으로 설정했습니다.
00:35:01이제 우리가 GPU 결정을 내리는 방식은, 가장 중요하게 생각하는 하나의 차원을 먼저 고정해야 한다는 것입니다.
00:35:15따라서 프리미엄 챗의 경우 지연 시간이 확실히 그 대상이라고 말씀드렸습니다.
00:35:21그리고 비동기 워크로드의 경우, 단일 GPU에서 처리하고자 하는 최소 배치 크기가 두 번째 차원이 됩니다.
00:35:31따라서 이것들을 먼저 고정해야 합니다.
00:35:34그러면 프리미엄 챗 애플리케이션의 경우를 가정해 보겠습니다.
00:35:39대략 10밀리초의 지연 시간으로 진행할 수 있습니다.
00:35:44최소 배치 크기는 상관없습니다.
00:35:46대략 2 정도여도 괜찮습니다.
00:35:53좋습니다.
00:35:54단일 GPU에서 동시 사용자 7명 정도가 되겠네요.
00:35:59그리고 품질에도 집중하고 싶기 때문에 컨텍스트 제한이 매우 중요합니다.
00:36:07그래서 일부 GPU들을 살펴보게 됩니다.
00:36:10H100 80GB의 경우 시간당 8달러 정도입니다.
00:36:15하지만 제 300x는 어떨까요?
00:36:19그렇나요?
00:36:20네.
00:36:21대략 시간당 10달러 정도죠.
00:36:24따라서 앞서 수학적으로 공유해 드린 처리량 계산을 적용해 보면 100만 토큰당 비용이 어느 정도인지 산출할 수 있습니다.
00:36:34비용을 훨씬 더 낮출 수 있죠.
00:36:37그러므로 이러한 차원들을 고정한 상태에서 계산을 수행하고, 일종의 추론 비용을 줄이기 위해 적절한 GPU를 선택해야 합니다.
00:36:49이것이 적어도 추론 최적화를 위해 취할 수 있는 첫 번째 단계입니다.
00:36:56알겠습니다.
00:37:01자, 다음 슬라이드로 넘어가겠습니다.
00:37:04잠시만요.
00:37:08좋습니다.
00:37:10자, 이제 다음 주제는 모델 최적화에 관한 것입니다.
00:37:15우리는 이제 일부 문제점들과 그러한 문제점이 발생한 원인, 그리고 그 이유를 이해하는 기반을 다졌습니다.
00:37:23GPU 용량 문제를 어떻게 해결할 수 있을지 이야기해 보았죠.
00:37:29이제 그 외에 무엇을 더 할 수 있는지 이해해야 합니다.
00:37:33바로 모델 최적화에 대한 내용인데, 탄마이(Tanmay)님을 초대하고 싶습니다.
00:37:39탄마이님은 연구 시절 이와 관련된 작업을 하셨기 때문에 모델 최적화에 대해 더 자세히 말씀해 주실 수 있을 겁니다.
00:37:47좋습니다.
00:37:48좋습니다.
00:37:49제가 화면을 넘기겠습니다.
00:37:50제가 제어할게요.
00:37:54네.
00:37:55여기서요.
00:37:56알겠습니다.
00:37:57안녕하세요 여러분.
00:37:58마이크 테스트입니다.
00:37:59드디어 제 목소리가 들리나요?
00:38:00네.
00:38:01좋습니다.
00:38:02안녕하세요.
00:38:03저는 탄마이 샤(Tanmay Shah)입니다.
00:38:04시니어 퀀트 모델러로 일하고 있고, AI 연구원이기도 합니다.
00:38:08주로 에이전트 검증에 초점을 맞추고 있으며, 현재는 세계 모델(world model)을 구축하고 있습니다.
00:38:13이번 주제는 모델 최적화입니다.
00:38:16모델 최적화를 시작하기에 앞서, 이 모든 복잡한 내용을 쉽게 이해할 수 있도록 연구 템플릿을 하나 만들었습니다.
00:38:25저희 템플릿은 간단합니다.
00:38:28첫째, 문제를 식별합니다.
00:38:30둘째, 두 가지 알고리즘을 사용해 문제를 해결합니다.
00:38:34이것은 가상의 알고리즘일 뿐입니다.
00:38:35첫 번째 알고리즘은 타조 알고리즘(ostrich algorithm)이라고 부릅니다.
00:38:39타조처럼, 문제가 나타나면 타조가 모래 속에 머리를 파묻는 것과 같습니다.
00:38:46우리도 똑같이 할 겁니다.
00:38:47문제에 직면할 때마다 그냥 무시해 버리는 거죠.
00:38:51이것이 우리가 따라야 할 중요한 알고리즘입니다.
00:38:55두 번째로 만든 것은 월드컵 알고리즘이라고 합니다.
00:38:59예를 들어, 이번 FIFA 월드컵에서 누가 우승할지 우리는 모릅니다.
00:39:03그래서 주최측은 48개 팀을 12개 조로 나누었습니다.
00:39:11그런 다음 32강전을 치르고, 현재는 32강전이 진행 중이죠.
00:39:16그다음에 16강, 8강, 4강, 그리고 결승전으로 이어집니다.
00:39:21그들이 하는 일은 문제를 더 작은 문제로 쪼개고, 유용한 결과물들을 다음 단계로 진출시키는 것입니다.
00:39:30이 모델 최적화와 모든 과정들을 이해하기 위해 이와 동일한 비유와 알고리즘을 사용할 것입니다.
00:39:38그럼 시작해 볼까요.
00:39:41자, 제게 H100 GPU가 하나 있습니다.
00:39:46이 오픈소스 모델을 사용해야 하는데, GPT OSS 120B(1200억) 파라미터 모델이라고 불리는 것입니다.
00:39:54현재 제 생각에는 BF16으로 학습되었고 가중치 용량이 240기가바이트입니다.
00:40:02어떻게 해야 할까요?
00:40:04이것이 우리 앞에 놓인 문제입니다.
00:40:07첫 번째로 해야 할 일은, 모델은 240기가바이트인데 H100은 80기가바이트라는 점입니다.
00:40:16여러 개의 GPU가 아니라 오직 하나의 GPU에만 모델을 올려야 합니다.
00:40:21그렇다면 무엇을 할 수 있을까요?
00:40:22제 생각에 간단한 방법은 그냥 압축하는 것입니다.
00:40:27하지만 어떻게 압축해야 할까요?
00:40:29이것이 또 다른 과제입니다.
00:40:30만약 BF16을 FP8로 압축하면, 크기가 약 120기가바이트가 될 것입니다.
00:40:38하지만 우리의 H100 GPU는 여전히 80기가바이트 용량입니다.
00:40:42그래서 그들은 한 걸음 더 나아가 MXFP4로 압축한 것으로 생각합니다.
00:40:49그렇게 하면 크기가 약 65기가바이트 정도가 됩니다.
00:40:53이것이 바로 우리가 할 수 있는 압축 방식이지만, 의문이 생깁니다.
00:40:59여기서 우리는 타조 알고리즘을 적용할 겁니다.
00:41:03더 큰 모델을 더 작은 크기로 압축할 때 손실이 전혀 없다고 가정하는 것이죠.
00:41:10두 번째로, 이 슬라이드에서, 아 네.
00:41:16이 슬라이드에서는 미스트랄 7B(Mistral 7B)를 사용했습니다.
00:41:2070억 개의 파라미터죠.
00:41:2270억 파라미터의 작은 모델입니다.
00:41:25여기에 2바이트를 곱해보면, 모델의 가중치 용량은 대략 14...
00:41:3114.5기가바이트가 되며, 이는 H100이나 심지어 A40에도 쉽게 들어갈 수 있습니다.
00:41:38다음으로 미스트랄 7B를 16비트 부동소수점으로 유지하는 대신, INT8, INT4, NF4 같은 다양한 기법을 적용할 수 있습니다.
00:41:53기본적으로 타조 알고리즘을 사용해 품질 저하 같은 것은 전혀 없다고 믿어버리면 됩니다.
00:42:01하지만 어떻게든 외부 벤치마크 테스트를 통해 제대로 작동하는지 수학적으로 증명해야 하기도 합니다.
00:42:10이러한 과정은 사후 학습 양자화(post-training quantization) 범주에 속합니다.
00:42:16파인튜닝을 진행하는 동안에도 이를 수행할 수 있습니다.
00:42:20이러한 종류의 양자화를 수행할 수도 있죠.
00:42:22이것은 양자화 인지 학습(quant-aware training)에 해당합니다.
00:42:25자, 다음 문제로 넘어가겠습니다.
00:42:31우리에겐 거대한 행렬들이 있습니다.
00:42:371000 곱하기 1000 차원의 행렬 A와, 또 다른 1000 곱하기 1000 행렬을 상상해 보세요.
00:42:51이 두 행렬을 곱하면 연산 횟수는 1000의 세제곱이 됩니다.
00:43:00이것은 컴퓨팅 측면에서 문제가 됩니다.
00:43:06따라서 우리는 행렬 곱셈이 빠르고 메모리를 절약하기를 원합니다.
00:43:13그럼 어떻게 해야 할까요?
00:43:15우리에게는 거대한 행렬이 있습니다.
00:43:17좋습니다, 4096 곱하기 4096 크기를 예로 들어 봅시다.
00:43:234096 곱하기 4096 행렬에서 연산을 속도 높이고 메모리를 절약하기 위해 무엇을 해야 할까요?
00:43:33첫째로, 월드컵 알고리즘을 사용할 것입니다.
00:43:37임의의 숫자를 정하고 블록을 수직으로 쪼개는 겁니다.
00:43:42어떤 숫자를 선택하든 상관없습니다.
00:43:454096개의 열이 있다고 해봅시다.
00:43:51이것을 각각 128개의 열을 가진 그룹으로 쪼갭니다.
00:43:57즉, 수직으로 128, 128, 128, 128, 128씩 나누는 거죠.
00:44:03이렇게 4096을 나누면 32개의 블록을 얻게 됩니다.
00:44:09그렇다면 이렇게 했을 때 어떤 일이 벌어질까요?
00:44:13이렇게 수직으로 분할하기만 하면 여러 개의 GPU를 사용하여 프로세스 속도를 높일 수 있습니다.
00:44:21이러한 방식을 멀티 헤드 어텐션(multi-head attention)이라고 부릅니다.
00:44:26그렇다면 또 무엇을 할 수 있을까요?
00:44:29앞서 언급했듯이 타조 알고리즘 같은 큰 행렬이 있습니다.
00:44:36우리의 주된 문제는 크기(sizing)입니다.
00:44:39따라서 32개의 수직 블록을 모두 유지하는 대신, 31개의 블록을 갖다 버리는 겁니다.
00:44:49그리고 단 하나의 블록만으로도 모든 쿼리를 처리하기에 충분하다고 가정하는 것이죠.
00:44:57성능 손실은 거의 무시할 수 있을 정도일 겁니다.
00:45:00그렇게 도출된 알고리즘이 있습니다.
00:45:04이 알고리즘을 멀티 쿼리 어텐션(multi-query attention)이라고 부릅니다.
00:45:08보시다시피, 현재 우리는 양극단에 서 있습니다.
00:45:12하나는 32개의 블록으로 쪼개서 서로 다른 GPU를 사용하거나 병렬 처리를 수행하는 멀티 헤드 어텐션이고,
00:45:22동시에 31개의 블록을 그냥 내다 버리는 방식도 있습니다.
00:45:26이것을 멀티 쿼리 어텐션이라고 부르는 것이죠.
00:45:31따라서 양쪽 극단 사이에서 어떤 중간 지점을 찾아야 합니다.
00:45:3831개를 전부 버리는 대신, 블록 중 일부를 그룹으로 묶을 수 있다고 말할 수 있습니다.
00:45:49그리고 유사한 블록들은 유사한 종류의 쿼리에 집중할 것이라고 가정하는 겁니다.
00:45:58이러한 기술이 바로 현재 매우 대중적인 그룹드 쿼리 어텐션(grouped-query attention)에 해당합니다.
00:46:04미스트랄이나 다른 모델들에서도 이 그룹드 쿼리 어텐션이 작동합니다.
00:46:11자, 이제 우리는 거대한 행렬을 갖고 있다는 것을 이해했습니다.
00:46:16원하는 대로 행렬을 나누고 약간의 수학적 계산을 거쳐,
00:46:19손실이 거의 무시할 수준이라는 것을 증명할 수 있습니다.
00:46:23그렇다면 또 무엇을 할 수 있을까요?
00:46:25그 후에, 이 그룹드 쿼리 어텐션 다음에는,
00:46:34보시다시피 우리에게는 거대한 행렬이 있습니다.
00:46:38하나는 키(key) 행렬이고 다른 하나는 밸류(value) 행렬입니다.
00:46:42그 행렬을 잠재 벡터(latent vector)로 압축해 봅시다.
00:46:47그런 다음 잠재 벡터로부터 원래 행렬을 재구성하는 알고리즘을 고안해 내는 겁니다.
00:46:55이러한 전략이 바로 여기에 속합니다.
00:46:59멀티 헤드 잠재 어텐션(multi-head latent attention)이죠.
00:47:02하지만 RoPE(Rotary Position Embedding)와 관련해서 또 다른 문제가 발생합니다. RoPE는 위치 종속적인 반면 이것은 위치 독립적인 측면이 있기 때문입니다.
00:47:10따라서 매핑이 가능하도록 키(key)에 대해서도 일부 인덱스를 포함해야 합니다.
00:47:16하지만 여전히 근본적인 문제는 왜 우리가 그토록 커다란 행렬들을 곱하고 있느냐는 것입니다.
00:47:25그 이유는 어텐션 메커니즘의 작동 방식 자체가 모든 토큰이 모든 토큰에 주의를 기울이기 때문입니다.
00:47:33그렇다면 이전의 모든 토큰에 주의를 기울이는 대신, 우리에게 중요한 토큰에만 주의를 기울이는 것은 어떨까요?
00:47:42그래서 이런 분야가 계속 발전하고 있습니다.
00:47:46이는 스파스(Sparse), 딥시크 스파스 어텐션에 해당합니다.
00:47:51그렇죠.
00:47:53네, 그럼 좋습니다.
00:47:56다음으로 넘어가죠.
00:47:59네, 다음은 플래시 어텐션입니다.
00:48:02플래시 어텐션에서 핵심적인 문제는 바로,
00:48:09현재는 거의 모든 사람이 플래시 어텐션을 사용하지만, 2022년이나 2023년 당시에는 방식이 달랐다는 점입니다.
00:48:20원래는 이런 식으로 작동했습니다.
00:48:23Q와 K, 즉 쿼리 및 키 행렬이 HBM(고대역폭 메모리)에 있었습니다.
00:48:34먼저 텐서 코어로 로드되어 연산을 수행한 다음, 다시 HBM에 기록하는 방식이었죠.
00:48:47그리고 이 과정이 여러 번 반복됩니다.
00:48:51플래시 어텐션이 취한 방식은 전체 행렬을 그대로 곱하는 대신,
00:48:59큰 행렬을 작은 타일로 쪼개는 방식으로 처리하는 것입니다.
00:49:05그리고 그 작은 타일들만 SRAM에 올려서 빠른 연산이 가능하게 하고,
00:49:13온라인 소프트맥스를 계산하기 위해 세 가지 변수를 계속 추적하는 방식입니다.
00:49:20네, 수학적인 내용인데요. 멀티 헤드 어텐션이 있고 KV가 524개라면,
00:49:34원하는 그룹화 수준에 따라 달라집니다. 32개의 KV 헤드 대신 8개의 KV 헤드만 사용하고 싶다면,
00:49:474배의 압축 효과를 얻을 수 있으며, 이것이 멀티 헤드 레이턴트 어텐션입니다.
00:49:54이 공식을 적용할 때는 모델마다 레이어 개수가 다르므로 모델별 차이가 있습니다.
00:50:00원래 딥시크 논문에서는 차원이 128이었나... 정확한 차원은 기억나지 않지만, 그에 따르면
00:50:11512차원의 하나의 레이턴트 벡터와 RoPE 인덱스를 위한 64차원을 사용했다고 합니다.
00:50:23이를 통해 멀티 헤드 어텐션보다 56배 더 압축되었다는 점을 보여주었습니다.
00:50:32좋습니다.
00:50:33네, 이것이 트레이드오프 다이어그램인데요. 여기서는 선형 어텐션이나 맘바(Mamba)에 대해 아직 다루지 않은 것 같네요.
00:50:50핵심 문제는 모든 행렬 곱셈입니다. 현재는 모두가 어텐션을 사용하고 있죠.
00:50:56만약 미래에 어텐션을 사용하고 싶지 않다면, 토큰을 순차적으로 생성하는 대신 모든 것을 동시에 생성할 수 있는 확산 모델(Diffusion model) 등을 사용할 수도 있을 겁니다.
00:51:07그러면 이 모든 알고리즘도 바뀌게 되겠죠.
00:51:14하지만 여기서는 선형 어텐션과 맘바라는 두 가지가 더 언급된 것 같습니다.
00:51:19이 슬라이드에 따르면, 아무것도 압축하지 않는 MHA는 그냥 프로세스를 병렬화하는 것입니다.
00:51:29품질 저하가 없기 때문에 좋고, 그 다음은 그룹드 쿼리 어텐션인데, 현재 거의 모든 모델이 GQA와 DSA 방식을 사용하고 있습니다.
00:51:42네.
00:51:43어텐션 메커니즘 스코어카드에서도 비슷한 내용을 제공하고 있습니다. MHA는 품질이 좋고 처리량(throughput)도 괜찮은 편입니다.
00:51:56그룹드 쿼리 어텐션의 경우 사용 사례에 따라 다릅니다. 품질은 멀티 헤드 어텐션과 거의 유사하지만 사용 사례 역시 매우 중요합니다.
00:52:10네, 멀티 쿼리 어텐션은 한쪽 극단에 있는 방식입니다.
00:52:13이유는 잘 모르겠지만, 오직 하나의 블록만 필요하고 모든 쿼리가 그 더 작은 블록을 참조한다고 가정하는 것이죠.
00:52:24그래서 MQA는 품질이 그렇게 뛰어나지는 않습니다.
00:52:29그리고 멀티 헤드 레이턴트 어텐션의 경우, 딥시크 모델들을 써보셨다면 아시겠지만 슬라이딩 윈도우 외에도 품질 면에서 훌륭한 성능을 보여줍니다.
00:52:44이 모든 것들이 윈도우를 조정하는 등의 기법들입니다. 선형 어텐션은 모든 것을 먼저 요약한 뒤 참조하자는 방식이고, 맘바는 상태 공간 모델(State-space model)입니다.
00:53:09모델 최적화를 위해 여기 두 개의 노트북(코드)도 준비되어 있습니다.
00:53:28여기로 이동해야겠네요.
00:53:35좋습니다. 양자화 데모를 볼까요? 이건 이미 실행되었나요? 아닙니다.
00:53:51한 번 실행해 보겠습니다.
00:53:54자, 미스트랄(Mistral) 7B 같은 모델을 로드하고 있습니다.
00:54:10이건 FP16 베이스라인을 사용하는 버전입니다.
00:54:20잠시만요.
00:54:21실행되었나요?
00:54:21잠시만요.
00:54:22실행되었나요?
00:54:23좋습니다.
00:54:242밀리초 만에 실행되었습니다.
00:54:27이것도 실행되었나요?
00:54:28좋습니다.
00:54:29이번에는 FP16 정밀도로 모델을 가져오고 있습니다.
00:54:35좋습니다.
00:54:362밀리초 만에 실행되었습니다.
00:54:40이것도 실행되었나요?
00:54:41좋습니다.
00:54:42이번에는 FP16 정밀도로 모델을 가져오고 있습니다.
00:54:47와이파이 때문에 말이죠.
00:54:58시간이 좀 걸릴 겁니다.
00:55:03알겠습니다.
00:55:08허깅 페이스에서 가중치를 다운로드하고 있기 때문에 시간이 걸립니다.
00:55:14어?
00:55:17네, 코랩(Colab)은 온라인으로 실행되니까요.
00:55:22네.
00:55:23허깅 페이스에 네트워크 요청을 보내서 가져와야 하기 때문입니다.
00:55:30다운로드하는 데 시간이 좀 걸리는 것 같네요.
00:55:35알겠습니다.
00:55:36알겠습니다.
00:55:37알겠습니다.
00:55:38알겠습니다.
00:55:39알겠습니다.
00:55:40여기서 보시다시피 FP16 정밀도에서의 메모리 크기는 대략 15GB 정도입니다.
00:56:00우리는 탈무드가 이야기했던 것 처럼 INT8을 이용해 2배 압축을 시도하고 있습니다.
00:56:15알겠습니다.
00:56:16보시다시피 메모리 크기가 이제 0.7GB, 0.5GB 정도로 줄어듭니다.
00:56:21이것이 의미하는 바는 KV가 성장할 수 있는 메모리 여유가 더 생긴다는 뜻입니다.
00:56:27즉, 더 긴 컨텍스트 제한을 처리하거나 더 많은 동시 사용자를 수용할 수 있게 된다는 의미죠.
00:56:36INT4를 사용하면 기본적으로 4배 압축을 수행하게 됩니다.
00:56:41따라서 4배 압축을 거치면 메모리가 훨씬 더 줄어듭니다.
00:56:453~4GB 정도가 되겠네요.
00:56:50네, 4.5GB 정도입니다.
00:56:51그리고 네.
00:56:52잠시만요.
00:56:53이것은 기본적인 그래프로, 대략적인 이론상의 수치입니다.
00:57:09여기서 별도의 처리량 테스트를 진행하는 것은 아닙니다.
00:57:12하지만 보통 메모리가 늘어나면...
00:57:15처리량도 약간 더 높아지게 됩니다.
00:57:21저희가 연구한 일부 벤치마크에 따르면 INT8 압축의 경우,
00:57:26처리량이 오히려 약간 낮아지기도 합니다.
00:57:32알겠습니다.
00:57:33그리고 어텐션 메커니즘에 대한 데모가 있습니다.
00:57:42어텐션에 관해서는, 알겠습니다.
00:57:45이걸 실행해야겠네요.
00:57:58좋습니다.
00:57:59실행되었습니다.
00:58:02어.
00:58:03잠깐만요.
00:58:04왜 GPU가 감지되지 않는다고 나오죠?
00:58:09GPU가 감지되어야 하는데요.
00:58:18아.
00:58:19그렇군요.
00:58:29잠깐만요.
00:58:30잠깐만요.
00:58:30잠깐만요.
00:58:50이거 의외네요.
00:58:57무슨 이유에서인지 GPU를 감지하지 못하는 것 같습니다.
00:59:05분명 여기에 GPU가 있는데 말이죠.
00:59:11알겠습니다.
00:59:12신경 쓰지 마세요.
00:59:14네.
00:59:14여기서 기본적인 아이디어는 멀티 헤드에서 그룹드 쿼리 어텐션, 그리고 MLA로 서로 다른 어텐션 메커니즘을 사용해 연산을 압축하는 방향으로 이동함에 따라,
00:59:26일부 최적화 효과를 눈으로 확인할 수 있게 된다는 것입니다.
00:59:33어젯밤에 벤치마킹을 좀 해봤는데요.
00:59:38이 부분은 정정하고 싶습니다.
00:59:4356배가 아니었습니다.
00:59:4514배였습니다.
00:59:4814배였어요.
00:59:50기본적으로 데모 계산 과정에서 레이어 수를 곱하지 않는 실수가 있었습니다.
01:00:02네.
01:00:03이 점은 사과드립니다.
01:00:04따라서 이 MLA는 멀티 헤드 어텐션에 비해 약 14배의 절감 효과가 있습니다.
01:00:15이제 페인 포인트(고충), 기초 개념, 그리고 모델 최적화 측면을 이해했으니, 서빙 측면에서는 무엇을 할 수 있는지 이야기해 보겠습니다.
01:00:31첫 번째로, 간단한 디코딩 단계를 수행할 때 모델 가중치를 불러오고 이전의 모든 토큰에 대한 키 및 값 벡터를 재계산하는 것을 보았습니다.
01:00:50이미 모든 토큰에 대해 해당 벡터들을 계산해 두었는데도 말이죠.
01:00:55따라서 분명 연산 낭비가 상당히 많습니다.
01:01:02시간 복잡도를 분석해 보면 O(N^2)이 나오게 됩니다.
01:01:07이를 해결하는 방법은 메모리와의 고전적인 트레이드오프입니다.
01:01:12토큰에 대응하는 이 벡터들을 메모리에 유지하고 해당 메모리를 참조하는 것이죠.
01:01:19그 메모리를 KV 캐시(KVCache)라고 부릅니다.
01:01:24전체적인 흐름은 대략 이렇습니다.
01:01:27이 KV 캐시를 바탕으로 네 가지 최적화 기법이 실제로 가능해졌습니다.
01:01:35첫 번째는 페이지드 어텐션(PagedAttention)에 관한 것입니다.
01:01:42그렇다면 오늘날의 차이점과 문제점은 무엇일까요?
01:01:45즉, 여러 개의 요청을 입력으로 GPU에 보낼 때, 이 요청들은 배치로 묶이게 됩니다.
01:01:52모든 요청에는 연속된 메모리 저장소가 할당되죠.
01:01:58예를 들어, 그냥 예시를 하나 들어서, 2 KV라고 해보죠.
01:02:05하지만 여러분의 요청에 실제로 필요한 건 1 KV 정도뿐이었다고 해봅시다.
01:02:11그럼 메모리의 50% 정도가 단편화되는 셈입니다.
01:02:19그리고 이 단편화는 기본적으로 메모리 낭비로 이어지죠.
01:02:24즉, 메모리 상에는 더 많은 요청을 처리할 수 있는 공간이 있었음에도 불구하고 연속된 메모리 블록을 찾고 있었기 때문에 처리하지 못하게 됩니다.
01:02:36그래서 운영체제(OS)의 작동 방식에서 영감을 얻었습니다.
01:02:41논리 메모리를 유지하고 기본적으로 물리 메모리를 따로 두는 방식이죠.
01:02:47따라서 논리 메모리 관점에서는 모든 토큰의 KV 벡터가 마치 연속되어 있는 것처럼 느껴집니다.
01:02:59하지만 실제로는 서로 다른 물리 주소에 매핑되죠.
01:03:06이 방식은 정말 많은 메모리를 절약하는 데 도움이 되었습니다.
01:03:11그리고 메모리를 일련의 블록으로 간주했기 때문에만 가능한 일이었죠.
01:03:18요청이 필요로 하는 만큼 그 블록들을 동적으로 할당하게 됩니다.
01:03:22새로운 토큰들이 들어오고 그러한 메모리가 필요할 때 말이죠.
01:03:27또 다른 요소는, 여러 요청을 배치로 보낼 때 발생하는 문제입니다.
01:03:39GPU는 그런 요청들을 받아 처리하죠.
01:03:42하지만 해당 배치 내의 모든 요청이 완료될 때까지는 새로운 배치를 받아들이지 않습니다.
01:03:49따라서 다이어그램은 페이징 기법과 비슷해 보입니다.
01:03:52하지만 여기서는 GPU가 언제 다음 배치를 처리할 수 있는지가 더 핵심입니다.
01:03:59즉, GPU가 완전히 유휴 상태로 놀고 있는 시간대가 존재하게 되죠.
01:04:04우리는 바로 이 문제를 해결하고 싶어 합니다.
01:04:08그래서 나온 아이디어가 바로 '연속 배치(Continuous Batching)'입니다.
01:04:17연속 배치는 또한 처리량(Throughput)을 높이는 데도 큰 도움이 됩니다. 이제 더 많은 요청을 꽤 빠르게 처리할 수 있으니까요.
01:04:24GPU가 항상 바쁘게 일하고 놀지 않도록 계속해서 유지해 주는 것이죠.
01:04:33결과적으로 연산 자원을 아끼게 됩니다.
01:04:36세 번째는 바로 프리픽스 캐싱(Prefix Caching)입니다.
01:04:39앞서 KV 캐시가 단일 요청 내의 토큰들에 대한 연산을 절약해 준다고 말씀드린 것 기억하시죠?
01:04:46하지만 여러 요청에 걸쳐 동일한 토큰들이 존재한다면 어떨까요?
01:04:53그 중복을 어떻게 절약할 수 있을까요?
01:04:55VLLM에서 도입한 프리픽스 캐싱이 바로 그 문제를 정확히 해결해 줍니다.
01:05:04그리고 세 번째는... 아니, 네 번째에 대해 이야기했군요.
01:05:10모델 양자화에 대해 이야기했지만, KV 가중치도 양자화할 수 있습니다.
01:05:21즉, 이제 키와 값 벡터를 위해 더 적은 공간만 필요하다는 뜻이죠.
01:05:28이 말은 메모리에서 더 많은 키와 값 벡터를 처리할 수 있다는 의미입니다.
01:05:32결과적으로 더 많은 토큰을 처리할 수 있고,
01:05:34더 긴 컨텍스트 한계를 지원할 수 있으며,
01:05:37더 높은 모델 품질을 제공할 수 있게 됩니다.
01:05:41그리고 이 모든 기능은 이미 VLLM에 구현되어 있습니다.
01:05:51굳이 바퀴를 다시 발명할 필요가 전혀 없죠.
01:05:56이 VLLM을 프로덕션 환경에 배포하기만 하면 성능 향상을 직접 확인할 수 있습니다.
01:06:03자, 다음으로 우리가 진행한 벤치마크 결과가 있습니다.
01:06:08이 벤치마크가... 자료가 있는지 한번 확인해 볼게요.
01:06:14여기 있네요.
01:06:17데모 화면입니다.
01:06:22이 벤치마크를 실행하는 데는 약 한 시간이 걸립니다. VLLM 서버를 계속해서 중지하고 재시작해야 하며, 모델을 로드하는 등의 작업이 필요하기 때문이죠.
01:06:35테스트를 수행하는 데 꽤 많은 시간이 걸리지만, 여기서 우리가 무엇을 하고 있는지 확실히 설명해 드릴 수 있습니다.
01:06:41우선 모델은 Mistral 7B로 동일하게 유지했습니다.
01:06:46그리고 보내고자 하는 일련의 입력 질문들이 있죠.
01:06:53이것들을 프롬프트라고 생각하시면 됩니다.
01:06:56그런 다음 서버가 실행 중인지 확인하는 등의 몇 가지 도우미 함수(helper function)가 있습니다.
01:07:01여기서 서버는 VLLM 서버를 의미합니다.
01:07:04그 후 VLLM 메트릭을 가져오는 도우미 함수들도 있고요.
01:07:09이 메트릭들이 무엇을 의미하는지에 대해서도 이야기하겠습니다.
01:07:14그 외에도 많은 벤치마크 코드들이 있습니다.
01:07:17그리고 KV 사용량 등을 측정해야 하죠.
01:07:22이러한 것들이 바로 도우미 함수들입니다.
01:07:24베이스라인(기준선)은 아주 간단합니다.
01:07:26Hugging Face 베이스라인을 사용했는데요.
01:07:29이것은 LLM에 날것 그대로 텍스트를 보내고 응답을 받아오는 방식입니다.
01:07:36여기서 몇 가지 결과를 볼 수 있습니다.
01:07:38Hugging Face의 처리량은 초당 약 51개 토큰 정도라는 것을 확인했습니다.
01:07:44첫 토큰 생성 시간(TTFT)은 54였고요.
01:07:46토큰 간 지연 시간은 19였습니다.
01:07:49이 모든 테스트는 H100에서 실행되었습니다.
01:07:56그런 다음, 아주 기본 설정의 VLLM 서버를 실행합니다.
01:08:00기본적으로 VLLM은 페이징 기법, 연속 배치, 그리고 KV 캐싱을 제공합니다.
01:08:08즉, 세 가지 기능이 기본적으로 포함되어 있죠.
01:08:13이 벤치마크들을 비교해 보면, 처리량이 거의 15배 가까이 증가하는 것을 볼 수 있습니다.
01:08:21초당 더 많은 토큰을 처리할 수 있게 되는 것이죠.
01:08:24그리고 첫 토큰 생성 시간도 늘어납니다.
01:08:34토큰 간 지연 시간은 다소 줄어들고요.
01:08:38사용자 및 컨텍스트 대비 KV 캐시 사용량은 확실히 증가합니다.
01:08:43자, 여기에 프리픽스 캐싱을 적용해 보면 어떨까요.
01:08:51프리픽스 캐싱을 적용하면 처리량이 더욱 증가하는 것을 볼 수 있습니다.
01:08:57TTFT(첫 토큰 생성 시간)는 감소합니다.
01:08:59토큰 간 지연 시간은 거의 비슷합니다.
01:09:02그리고 사용자 대비 KV 캐시 사용량은 약간 감소하는 경향을 보입니다.
01:09:09컨텍스트 대비 사용량은 줄어들지 않고요.
01:09:12거의 비슷합니다.
01:09:14이 부분도 거의 비슷한 것 같네요.
01:09:16그렇게 엄청난 차이가 나는 것은 아닙니다.
01:09:19여기에 추가로 KV 양자화를 적용하면 어떻게 될까요.
01:09:25처리량은 거의 비슷하다는 것을 알 수 있습니다.
01:09:33첫 토큰 생성 시간도 비슷하고요.
01:09:36토큰 지연 시간도 비슷합니다.
01:09:39하지만 KV 사용량은 실제로 감소합니다.
01:09:42키-값 공간을 양자화했기 때문입니다.
01:09:49그리고 탄마이(Tanmay)가 이야기할 추론 가속(Speculative Decoding) 개념이 있습니다.
01:09:54이것들을 벤치마킹해 보면, KV 사용량이 약간 줄어드는 것도 확인할 수 있습니다.
01:10:06결과 자체는 대동소이하지만요.
01:10:08전반적으로 이것들이 바로 여러 조건에서의 메트릭들입니다.
01:10:21화면을 축소해야겠네요.
01:10:25좋습니다.
01:10:26안 되네요.
01:10:27축소.
01:10:28작동하지 않네요.
01:10:29참 좋습니다.
01:10:30네, 이것이 바로 VLLM 벤치마크 결과입니다.
01:10:35참고로 프로덕션 환경의 기본 설정이기도 하죠.
01:10:38다른 엔진들에 대해 이야기할 때 이 의사 결정 트리(decision tree)도 공유해 드리겠습니다.
01:10:48그럼 이어서 우리가 적용할 수 있는 다른 추론 최적화에는 어떤 것들이 있는지 이야기해 봐야겠네요.
01:10:58그리고 그 외에 등장한 다른 솔루션들에는 무엇이 있었는지도요.
01:11:02다시 한번 탄마이를 초대하고 싶습니다.
01:11:07탄마이가 이러한 최적화들에 대해 이야기해 줄 겁니다.
01:11:11아, 죄송합니다.
01:11:12정말 죄송합니다.
01:11:13슬라이드를 띄우는 걸 깜빡했네요.
01:11:26뭐였더라?
01:11:27좋습니다.
01:11:28됐어요.
01:11:29완벽합니다.
01:11:30어느 거지?
01:11:31추론 가속이요.
01:11:32네.
01:11:33고마워요, 하샬.
01:11:34네.
01:11:35이 모든 것들이 추론 가속(Speculative Decoding)과 관련이 있습니다.
01:11:40이 기술들은 모두... 뭐라고 해야 할까요, 똑같은 탄산음료의 다른 맛 같은 것들입니다.
01:11:46이 기법은 디코딩 가속기 범주에 속합니다.
01:11:51첫 번째로, 추론 가속뿐만 아니라 Self-speculative, Eagle, Medusa 같은 다른 변형들도 있습니다.
01:12:01개인적으로는 이 중에서도 Eagle 알고리즘이 마음에 듭니다.
01:12:05그럼 추론 가속부터 시작해 보죠.
01:12:06좋습니다.
01:12:07자.
01:12:08추론 가속이란 무엇인지부터 시작해 보죠.
01:12:09주요 문제는 트랜스포머 아키텍처에서는 이 모든 토큰이 순차적으로 하나씩 하나씩 생성된다는 점입니다.
01:12:26더 작은 모델을 사용해서, 작은 모델이 4개 또는 5개 정도의 토큰을 먼저 생성하도록 하면 어떨까요?
01:12:37그리고 이 교사 모델, 혹은 우리의 월드컵 알고리즘에 비유하자면 심판이라고 할 수 있는 모델이 있죠.
01:12:43이 심판이 토큰을 몇 개나 수락할지 결정합니다.
01:12:48그리고 이 과정이 계속해서 반복됩니다.
01:12:51우리의 가정은 이런 방식이 효과를 발휘하는 특정 도메인이 존재한다는 것입니다.
01:12:59창의성이 거의 필요 없는 코딩 같은 분야가 그 예가 될 수 있겠죠.
01:13:05각 코드나 구문이 거의 유사하니까요.
01:13:08그래서 도움이 될 수 있습니다.
01:13:10하지만 제가 직접 테스트해 본 결과, 이 추론 가속 기법은 전혀 쓸모가 없었습니다.
01:13:18하지만 교사 모델에 보조 헤드가 하나 더 있어서 베이스 모델이나 작은 모델이 하는 것과 비슷한 역할을 하는 자기 추론 가속 같은 다른 기법들도 있습니다.
01:13:35그러다가 EGLE이 나왔죠. EGLE 1, 2, 3 버전이 얼마나 있는지 모르겠지만, 토큰을 직접 생성하는 대신 작은 모델을 학습시켜 메인 모델의 레이어 중 하나에서 특성(feature)을 가져와 토큰 대신 이 특성을 생성하게 하자는 것입니다.
01:14:02따라서 EGLE은 다른 종류의 기술들에 비해 더 낫습니다.
01:14:10그리고 또 다른 하나는 MEDUSA인데, 이들은 이 모든 토큰을 병렬로 생성하자고 말합니다.
01:14:17네, 자 여기 이 슬라이드에서요.
01:14:21네.
01:14:22다음 슬라이드요.
01:14:24알겠습니다.
01:14:25좋습니다.
01:14:26네, 알겠습니다.
01:14:27좋습니다.
01:14:28이제 프리픽스 캐싱에 대해 이야기해 보겠습니다.
01:14:34사람들이 정적 프리픽스 캐싱을 사용하고 있는지 잘 모르겠습니다.
01:14:39하지만 프리픽스 캐싱의 가장 큰 문제는 때때로 우리가 타이핑을 하다가 사소한 실수를 한다는 점입니다.
01:14:47이 표준적인 정적 프리픽스 캐싱은 기본적으로 프롬프트를 받아 해싱을 수행합니다.
01:14:53그리고 다음에 사용자가 비슷한 질문을 하면 그 해시를 매칭하려고 시도하죠.
01:14:58따라서 해시가 일치하면 그 모든 K와 V를 다시 연산하는 대신 저장소에서 바로 가져옵니다.
01:15:09하지만 아시다시피 가끔 실수를 하거나 단어이나 글자 하나를 바꾸기도 합니다.
01:15:15그렇게 되면 캐시 미스율이 아주 높아지게 됩니다.
01:15:21그래서 바로 이 Radix 트리가 등장했습니다.
01:15:25에이전트의 대두와 함께 Radix 트리가 매우 인기를 얻고 있습니다.
01:15:30제 생각에는 거의 모든 사람이 에이전트를 다루고 있으며, 대부분의 연산은 테스트 시점이나 추론 과정에서 일어납니다.
01:15:38비슷한 종류의 질문과 프롬프트를 계속해서 던지는 상황 말입니다.
01:15:42예를 들어, “당신은 전문 소프트웨어 엔지니어입니다”라는 말을 200번 반복하는 식이죠.
01:15:48이러한 종류의 루프가 에이전트 시스템 내부에서 계속해서 반복됩니다.
01:15:55그렇기 때문에 유사한 내용들을 Radix 트리에 유지하거나 저장하는 것이 필수적입니다.
01:16:03Radix 트리는 분기가 없는 노드를 병합하는 방식으로 프리픽스 트리를 발전시킨 형태입니다.
01:16:17동일한 작업을 계속해서 반복하는 이러한 작업 부하에서
01:16:24Radix 트리가 큰 도움이 되며, sglang은 프리픽스 캐싱을 위해 이러한 알고리즘을 사용합니다.
01:16:35네, 그리고 또 다른 항목이 있습니다.
01:16:38바로 TensorRT-LLM입니다.
01:16:41이게 참 헷갈립니다.
01:16:42제가 처음 시작했을 때도 그냥 혼란스러웠습니다.
01:16:46TensorRT-LLM이란 도대체 무엇일까요?
01:16:49TensorRT는 표준 SDK 같은 것입니다.
01:16:55TensorRT-LLM은 그저 추론 엔진일 뿐이죠.
01:16:59vLLM이나 sglang처럼 말입니다.
01:17:01하지만 문제는 이것이 NVIDIA와 연관되어 있다는 점입니다.
01:17:05그들은 모든 레이어와 모든 문제를 최적화했습니다.
01:17:10앞서 월드컵 알고리즘에서 언급했듯이, 모든 것을 쪼개고 하드웨어 수준에서까지 최적화를 거쳤습니다.
01:17:18네, 좋습니다. 다음이요.
01:17:23네, 이번 워크숍을 위해 어떤 것이 가장 좋은지 벤치마크도 진행해 보았습니다.
01:17:33저희의 테스트 환경은 대략 이렇습니다.
01:17:36두 가지 테스트를 진행했습니다.
01:17:39첫 번째는 에이전트 테스트를 제외한 환경으로, 단순히...
01:17:44ShareGPT 데이터셋을 사용하여 vLLM과 sglang으로 질문들을 던져보는 방식이었습니다.
01:17:57좋습니다.
01:18:05네, 좋습니다.
01:18:07화면을 좀 확대하겠습니다.
01:18:12네, 좋습니다.
01:18:13이번 워크숍에서는 H100을 사용했고, 첫 번째 테스트는 다음과 같이 진행했습니다.
01:18:23ShareGPT에서 질문을 가져와 vLLM과 sglang에 입력해 본 결과, 둘 중 어느 쪽이 더 우수한지 통계적으로 유의미한 차이는 없다는 것을 발견했습니다.
01:18:34즉, 둘은 거의 유사한...
01:18:37초당 처리 요청 수, 첫 토큰 생성 시간(TTFT), 지연 시간 측면에서 모두 비슷한 성능을 보여주었습니다.
01:18:43다만 유일한 차이는 에이전트 분기(branching) 테스트에서 관찰되었습니다.
01:18:50우리가 진행한 방식은 “당신은 세계 최고의 소프트웨어 엔지니어이다”라는 전제 하에 질문을 던지는 것이었습니다.
01:18:59예를 들면 도시의 교통 체증 문제를 해결하라는 식이었죠.
01:19:04그런 다음 이를 LLM에 입력합니다.
01:19:08LLM이 결과물을 생성합니다.
01:19:10그 후 두 번째 라운드도 진행했습니다.
01:19:13LLM이 결과물을 생성하면, 두 번째 라운드에서는 특히 다음과 같은 지시를 내렸습니다.
01:19:22제안서를 검토하고 1점부터 10점까지 평점을 매겨달라고 요청했죠.
01:19:28이렇게 두 번의 턴을 거쳤고, 이 루프가 계속해서 반복됩니다.
01:19:35저희가 발견한 바로는 모든 것이 표준화된 이러한 종류의 워크플로우에서는 모든 프롬프트와 컨텍스트 엔지니어링이 중요하게 작용합니다.
01:19:47따라서 이러한 에이전트 분기를 적절히 수행한다면 SGLang이 3~4배 더 우수하다고 볼 수 있습니다.
01:19:54물론 이 역시 어떤 세팅을 쓰느냐에 따라 달라질 수 있습니다.
01:19:58직접 테스트해보시면 다른 결과를 얻으실 수도 있습니다.
01:20:02알겠습니다.
01:20:03네.
01:20:04그래서 제 생각에는...
01:20:06GitHub에 업로드했었나요?
01:20:08네.
01:20:09알겠습니다.
01:20:10네.
01:20:11PDF 파일도 드라이브에 올라와 있습니다.
01:20:15슬라이드와 같은 링크입니다.
01:20:18간단히 요약해 드리겠습니다.
01:20:22표준 API 워크로드 처리량 측면에서는 vLLM과 SGLang이 거의 동일합니다.
01:20:31따라서 만약 특별한...
01:20:33표준 워크로드를 다루고 계신다면 무조건 vLLM을 선택하세요.
01:20:36어차피 프로덕션 환경의 기본값이니까요.
01:20:38하지만 Tanmay가 말했듯이 에이전트 워크로드를 구축하려고 할 때 바로 SGLang이 진가를 발휘합니다.
01:20:50모든 이점을 제공해 준다고 볼 수 있죠.
01:20:55그렇습니다.
01:20:58기본값으로는 vLLM을 유지하시고요.
01:21:00하지만 에이전트 워크로드가 있다면 SGLang 쪽으로 전환을 고려해 보세요.
01:21:05기존 vLLM 부문에 만족하지 못하신다면 말이죠.
01:21:09알겠습니다.
01:21:10잠시만요...
01:21:15기다려 보세요.
01:21:18네.
01:21:21그리고 또...
01:21:29120B 모델에 대한 비교가 있습니다.
01:21:33GPT OSS 120B 모델 말입니다.
01:21:36이것은 PlayPy에서 준비한 벤치마크입니다.
01:21:42여기에 블로그 링크가 있습니다.
01:21:46오, 좋네요.
01:21:48좋습니다.
01:21:49네.
01:21:50그들도 비슷한 벤치마크를 진행했고 TensorRT-LLM을 포함시켰습니다.
01:21:57확실히 이러한 벤치마크들을 살펴보면 여러분의 유스케이스에 가장 적합한 것이 무엇인지 파악하는 데 도움이 될 것입니다.
01:22:05앞서 언급했듯이 TensorRT는 하드웨어 측면도 최적화하여 최고의 하드웨어 성능을 이끌어내려고 합니다.
01:22:16그리고 vLLM, SGLang, TensorRT 중에서 어떤 엔진을 쓸지 결정한 이후에 사용할 수 있는 새로운 엔진들도 등장하고 있습니다.
01:22:29대표적으로 NVIDIA Dynamo가 있죠.
01:22:43이것 역시 에이전트 세션 라우팅을 위한 것입니다.
01:22:49Hugging Face도 항상 존재합니다.
01:22:51가볍게 참고할 만하죠.
01:22:53그리고 최근 스탠퍼드에서 제안한 MSTAR 엔진도 있습니다.
01:23:00멀티모달을 위한 NVIDIA Dynamo도 있고요.
01:23:05이런 것들도 충분히 탐색해 보실 수 있습니다.
01:23:08간단히 요약하자면, 먼저 베이스라인부터 시작합니다.
01:23:15우리의 유스케이스에 적합한 모델이 무엇인지 찾으려고 노력하죠.
01:23:22DeepSeek을 선택할 수도 있습니다.
01:23:27Mistral 7B 같은 모델은 고르지 마세요.
01:23:30별로 좋지 않거든요.
01:23:32아무튼 그렇습니다.
01:23:35모델을 선택한 후 더 작은 메모리 공간에 더 큰 모델을 우겨넣고 싶을 때가 있습니다.
01:23:44GPU 비용을 아끼기 위해서죠.
01:23:47그럴 때 각종 양자화(quantization) 기법을 활용할 수 있습니다.
01:23:51그런 다음 내부적으로 적절한 서빙 엔진을 사용하여 서빙 최적화를 적용할 수 있습니다.
01:23:58이를 통해 정말로 원하는 처리량을 확보할 수 있습니다.
01:24:07그리고 집에 돌아간 후에 해볼 수 있는 일로는, 여기서 모든 자료를 다룰 수는 없으니 다양한 어텐션 메커니즘이나 여러 엔진에 대한 관련 정보를 읽어보는 것입니다.
01:24:27온라인에 공개된 다양한 벤치마크들도 읽어보시고요.
01:24:34그 다음 단계로 KV 캐시 축출 전략 등 심화 가이드나 후속 단계에 대한 내용들이 많이 있습니다.
01:24:45요즘 트렌드는 별도의 KV 캐시 엔지니어링 분야가 생겨나는 추세입니다.
01:24:50따라서 그 안에서 무슨 일이 일어나고 있는지 이해해야 합니다.
01:24:52KV 축출, 캐시 압축, 하이브리드 메모리 같은 것들 말이죠.
01:24:57이와 관련해서 정말 많은 솔루션들이 나오고 있습니다.
01:25:01항상 기초나 근본 원리에 집중하려고 노력하세요.
01:25:08어떤 솔루션이 어떤 문제를 해결하는지, 그리고 여러분의 유스케이스에서 실제로 그 문제를 해결할 필요가 있는지 확인해 보세요.
01:25:17그리고 분산 LLM 추론이라는 완전히 다른 핵심 주제도 존재합니다.
01:25:26내부 구조를 모두 살펴보고 실습까지 하려면 아마 두 시간짜리 워크숍이 필요할 것입니다.
01:25:40네, 이건 우리가 AI 엔지니어 뉴욕 세션에서 제안하려고 하는 내용인데, LLM 추론의 고급 섹션을 더 깊게 파고드는 것입니다.
01:25:51이번 워크숍은 초·중급자를 대상으로 한 성격이 더 강했습니다.
01:25:55따라서 이 양식을 통해 피드백과 함께 관심도 받을 수 있습니다.
01:26:02특정 섹션에 개선이 필요하다고 생각되시면 꼭 피드백을 남겨주세요.
01:26:09그리고 뉴욕 페어에서 이 워크숍을 보고 싶으시다면, 편하게 참여 의사를 등록해 주시기 바랍니다.
01:26:22네?
01:26:24아, 이게 어떻게 가능하죠?
01:26:27이런.
01:26:32잠깐 확인해 볼게요.
01:26:37좋습니다.
01:26:38네?
01:26:39네.
01:26:40URL은 잘 작동하죠?
01:26:41네.
01:26:42QR 코드가 아니라요?
01:26:43알겠습니다.
01:26:44제가 두 개를 연결하는 걸 깜빡했나 보네요.
01:26:45알겠습니다.
01:26:46좋습니다.
01:26:46네.
01:26:47그럼 그걸 주실 수 있다면요.
01:26:49알겠습니다.
01:26:50좋습니다.
01:26:51네.
01:26:52그럼 그걸 주실 수 있다면요.
01:26:53알겠습니다.
01:26:54네.
01:26:55알겠습니다.
01:26:56좋습니다.
01:26:57네.
01:26:58그럼 그걸 주실 수 있다면요.
01:26:59제가 좀...
01:27:00알겠습니다.
01:27:00알겠습니다.
01:27:01좋습니다.
01:27:02네.
01:27:02그럼 그걸 주실 수 있다면요.
01:27:03제가 좀...
01:27:04알겠습니다.
01:27:05그럼 되겠네요.
01:27:06음, 그리고 네, 이제 이 워크숍을 마무리하면 좋을 것 같습니다.
01:27:13그리고 여러분 중 많은 분이 질문이 있으실 거예요.
01:27:14그래서 그런 것들은 오프라인으로 다루면 됩니다.
01:27:15어, 만나서 그런 질문들에 대해 이야기 나눌 수 있습니다.
01:27:16네.
01:27:17물론입니다.
01:27:18물론이죠.
01:27:19어, 모두 감사드립니다.
01:27:20참여해 주셔서 감사해요.
01:27:21어, 정말...
01:27:22어, 모두 감사드립니다.
01:27:23어, 모두 감사드립니다.
01:27:24참여해 주셔서 감사해요.
01:27:25어, 모두 감사드립니다.
01:27:26참여해 주셔서 감사해요.
01:27:27어, 정말...
01:27:28아, 알겠습니다.
01:27:29어, 알겠습니다.
01:27:30그럼 되겠네요.
01:27:31어, 그리고 네, 이제 이 워크숍을 마무리하면 좋을 것 같습니다.
01:27:33어, 그리고 네, 이제 이 워크숍을 마무리하면 좋을 것 같습니다.
01:27:36그리고 여러분 중 많은 분이 질문이 있으실 거예요.
01:27:39그래서 그런 것들은 오프라인으로 다루면 됩니다.
01:27:41어, 만나서, 어, 그 질문들에 대해, 어, 이야기 나눌 수 있습니다.
01:27:42네, 물론입니다.
01:27:43어, 모두 감사드립니다.
01:27:44어, 정말 의미 있었고 여러분 모두 이렇게 참석해 주셔서...
01:27:49어, 정말 감사드립니다.
01:27:50네, 감사합니다.
커뮤니티 글
아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!
이 영상에 대해 글쓰기