Triton 응답 캐시
Triton 응답 캐시 (Response Cache)
개요 (Overview)
이 문서에서 *추론 요청(inference request)*은 Triton에 제출된 요청을 이루는 모델 이름, 모델 버전, 입력 텐서(이름, 모양, 데이터 타입, 텐서 데이터)를 말해요. 추론 결과(inference result)는 추론 실행이 만들어낸 출력 텐서(이름, 모양, 데이터 타입, 텐서 데이터)예요. 응답 캐시는 Triton이 이전에 실행한 추론 요청에 대해 생성된 추론 결과를 보관하는 데 사용돼요. Triton은 응답 캐시를 유지해서 캐시에 적중(hit)한 추론 요청은 모델을 실행해 결과를 만들지 않고 캐시에서 그 결과를 추출하도록 해요. 일부 사용 사례에서는 이로 인해 추론 요청 지연 시간이 크게 줄 수 있어요.
Triton은 모델 이름, 모델 버전, 모델 입력을 포함하는 추론 요청의 해시로 응답 캐시에 접근해요. 해시가 캐시에서 발견되면 해당 추론 결과를 캐시에서 추출해 그 요청에 사용해요. 이렇게 되면 Triton이 모델을 실행해 추론 결과를 만들 필요가 없어요. 해시가 캐시에서 발견되지 않으면 Triton은 모델을 실행해 추론 결과를 만든 다음 그 결과를 캐시에 기록해서, 이후 추론 요청이 그 결과를 (재)사용할 수 있게 해요.
사용법 (Usage)
주어진 모델에 캐싱이 사용되려면 서버 쪽과 모델의 모델 구성 양쪽 모두에서 켜져야 해요. 자세한 내용은 아래 섹션들을 참고하세요.
서버 쪽 캐싱 켜기 (Enable Caching on Server-side)
응답 캐시는 Triton 서버를 시작할 때 캐시 구현 이름 <cache>와 해당 구성을 지정해 서버 쪽에서 켜요.
CLI로는 이것이 tritonserver --cache-config <cache>,<key>=<value> ...로 설정되는 걸 뜻해요. 예:
tritonserver --cache-config local,size=1048576
[!NOTE] 비대화형 쉘을 쓴다면 공백 없이
--cache-config=<cache>,<key>=<value>처럼 인자를 지정해야 할 수 있어요.
In-process C API 애플리케이션의 경우 이는 TRITONSERVER_SetCacheConfig(const char* cache_implementation, const char* config_json)을 호출하는 걸로 번역돼요.
이렇게 하면 사용자가 서버 시작 시 캐싱을 전역적으로 켜거나 끌 수 있어요.
모델의 캐싱 켜기 (Enable Caching for a Model)
기본적으로 --cache-config 플래그로 응답 캐시가 전역적으로 켜져 있어도 어떤 모델도 응답 캐싱을 사용하지 않아요.
주어진 모델이 응답 캐싱을 사용하려면 그 모델의 모델 구성에서도 응답 캐싱이 켜져 있어야 해요:
# config.pbtxt
response_cache {
enable: true
}
이렇게 하면 사용자가 특정 모델에 대해 캐싱을 켜거나 끌 수 있어요.
각 모델에 대한 응답 캐시 켜기에 대한 자세한 내용은 모델 구성 문서를 참고하세요.
캐시 구현 (Cache Implementations)
23.03 릴리스부터 Triton에는 사용자가 선택한 캐시 구현과 통신하는 데 쓰이는 TRITONCACHE API 집합이 있어요.
캐시 구현은 필수 TRITONCACHE API를 구현하는 공유 라이브러리이며, 켜져 있으면 서버 시작 시 동적으로 로드돼요.
Triton의 최신 tritonserver 릴리스 컨테이너에는 다음 캐시 구현이 기본 제공돼요:
- local:
/opt/tritonserver/caches/local/libtritoncache_local.so - redis:
/opt/tritonserver/caches/redis/libtritoncache_redis.so
이 TRITONCACHE API와 함께 tritonserver는 어떤 캐시 구현을 사용할지, 그리고 어떻게 구성할지 사용자가 유연하게 커스터마이즈할 수 있는 새 --cache-config CLI 플래그를 노출해요. --backend-config 플래그와 비슷하게 기대 형식은 --cache-config <cache_name>,<key>=<value>이고, 캐시 구현이 여러 키를 요구하면 여러 번 지정할 수 있어요.
Local 캐시
local 캐시 구현은 23.03 릴리스 이전에 내부적으로 사용되던 응답 캐시와 동일해요. 구현 관련 세부 정보는 local cache implementation을 참고하세요.
--cache-config local,size=SIZE가 0이 아닌 SIZE로 지정되면 Triton은 요청된 크기를 CPU 메모리에 할당하고 그 캐시를 모든 추론 요청과 모든 모델에 걸쳐 공유해요.
Redis 캐시
redis 캐시 구현은 Triton이 캐싱용 Redis 서버와 통신할 수 있는 기능을 노출해요. redis_cache 구현은 본질적으로 Triton과 Redis 사이의 중개자 역할을 하는 Redis 클라이언트예요.
Triton의 맥락에서 redis 캐시가 local 캐시보다 갖는 이점 몇 가지를 꼽자면:
- Redis 서버는 Triton이 접근 가능하기만 하면 원격으로 호스팅될 수 있어 Triton 프로세스의 수명에 직접 묶이지 않아요.
- 즉 Triton을 재시작해도 이전에 캐시된 항목에 여전히 접근할 수 있어요.
- 또한 Triton이 캐시와 메모리/리소스 사용 경쟁을 하지 않아도 된다는 뜻이에요.
- 여러 Triton 인스턴스가 각 Triton 인스턴스를 같은 Redis 서버와 통신하도록 구성해 하나의 캐시를 공유할 수 있어요.
- Redis 서버는 Triton과 독립적으로 업데이트/재시작될 수 있고, Redis 서버 다운 시간 동안 Triton은 캐시 접근 없이 동작하는 것처럼 폴백해 동작하며 적절한 오류를 로그해요.
일반적으로 Redis 서버는 사용 사례에 맞게 구성/배포하면 되고, Triton의 redis 캐시는 단순히 사용자의 Redis 배포의 클라이언트로 동작해요. Redis 서버 구성에 대한 질문·세부사항은 Redis 문서를 참고해야 해요.
Triton 특정 redis 캐시 구현 세부사항/구성은 redis cache implementation을 참고하세요.
커스텀 캐시 (Custom Cache)
TRITONCACHE API 인터페이스를 통해 사용자가 어떤 사용 사례별 요구를 충족하도록 자신만의 캐시를 구현할 수 있게 됐어요. 캐시 개발자가 구현해야 할 필수 인터페이스를 보려면 TRITONCACHE API 헤더를 참고하세요. local 또는 redis 캐시 구현을 참고 자료로 사용할 수 있어요.
커스텀 캐시를 성공적으로 개발하고 빌드하면 결과 공유 라이브러리(예: libtritoncache_<name>.so)를 local과 redis 캐시 구현이 있는 곳과 비슷한 캐시 디렉토리에 넣어야 해요. 기본적으로 이 디렉토리는 /opt/tritonserver/caches이지만 필요에 따라 --cache-dir로 커스텀 디렉토리를 지정할 수 있어요.
이 예제를 종합하면, 커스텀 캐시 이름이 "custom"(이 이름은 임의예요)이라면 기본적으로 Triton은 캐시 구현을 /opt/tritonserver/caches/custom/libtritoncache_custom.so에서 찾을 거예요.
폐기 참고 (Deprecation Notes)
Note 23.03 이전에는
local캐시 켜기가 Triton을--response-cache-byte-size플래그로 시작할 때 0이 아닌 크기(바이트)를 설정하는 방식으로 수행됐어요.23.03부터
--response-cache-byte-size플래그는 폐기됐고--cache-config를 대신 사용해야 해요. 역호환성을 위해--response-cache-byte-size는 대응하는--cache-config인자로 변환돼 내부적으로 계속 동작하지만, 기본적으로local캐시 구현을 사용해요.--response-cache-byte-size플래그로 다른 캐시 구현을 선택하는 것은 불가능해요.예를 들어
--response-cache-byte-size 1048576은--cache-config local,size=1048576과 동일해요. 그러나--cache-config플래그가 훨씬 더 유연하므로 그것을 사용해야 해요.
Warning
local캐시 구현은 내부 메모리 관리 요구 사항 때문에 매우 작은 값의--cache-config local,size=<small_value>또는--response-cache-byte-size(예: 1024바이트 미만)에서 초기화에 실패할 수 있어요. 상대적으로 작은 캐시 크기에서 초기화 오류가 발생하면 크기를 늘려 보세요.마찬가지로 크기는 시스템의 가용 RAM에 의해 상한이 정해져요. 매우 큰 캐시 크기 설정에서 초기 할당 오류가 발생하면 크기를 줄여 보세요.
성능 (Performance)
응답 캐시는 상당한 수의 중복 요청(캐시 적중)이 예상되어 캐싱의 이점을 받는 사용 사례에 사용하기 위한 거예요. 여기서 "상당한"이라는 표현은 사용 사례에 따라 주관적이지만, 간단히는 예상 캐시 적중/미스의 비율과 응답 계산에 걸리는 평균 시간을 고려하면 돼요.
캐시 적중이 흔하고 계산이 비싼 경우 캐시가 전반적인 성능을 크게 개선할 수 있어요.
대부분의 요청이 고유한(캐시 미스) 경우나 계산이 빠르고/저렴한(모델이 compute-bound가 아닌) 경우에는 캐시를 관리하고 통신하는 오버헤드 때문에 캐시가 전반적인 성능에 오히려 부정적 영향을 줄 수 있어요.
앙상블 모델 캐싱 (Ensemble Model Caching)
앙상블 내의 모든 구성 모델이 캐싱을 지원하면 앙상블 모델에 대한 최상위 요청도 캐싱을 지원해요.
마찬가지로 앙상블의 구성 모델이 캐싱을 지원하지 않으면 앙상블 모델도 그 한계를 물려받아 캐싱을 지원하지 않게 돼요. 어떤 유형의 모델이 캐싱을 지원하는지에 대한 알려진 한계는 아래를 참고하세요.
앙상블에서 캐시 적중이 발생하면 구성 모델에 요청을 보내는 것을 완전히 건너뛰고 앙상블 모델에서 캐시된 응답을 반환해요.
앙상블에서 캐시 미스가 발생하면 표준 추론으로 폴백하고 요청은 평소처럼 구성 모델로 진행돼요.
앙상블과 그 구성 모델은 각각 독립적으로 캐싱을 켤 수 있고, 켜지면 각자 자신의 캐시를 유지해요. 앙상블 레벨에서 캐시 미스가 발생하더라도, 구성되는 모델의 입력·출력에 따라 앙상블 내부의 중간 모델에서 캐시 적중이 발생할 수 있어요. 구성 모델은 앙상블 레벨에서 캐싱을 켜기 위해 캐싱을 켤 필요는 없어요.
알려진 한계 (Known Limitations)
- CPU 메모리에 있는 입력 텐서만 캐시 접근을 위해 해시될 수 있어요. 추론 요청에 CPU 메모리에 없는 입력 텐서가 포함되면 그 요청은 해시되지 않아 응답이 캐시되지 않아요.
- 모든 출력 텐서가 CPU 메모리에 있는 응답만 캐싱 자격이 돼요. 응답의 어떤 출력 텐서라도 CPU 메모리에 없으면 응답이 캐시되지 않아요.
- 캐시는 추론 요청 해시로만 접근돼요. 결과적으로 두 개의 서로 다른 추론 요청이 같은 해시를 생성하면(해시 충돌) Triton이 추론 요청에 대해 잘못된 캐시된 결과를 사용할 수 있어요. 해시는 64비트 값이라 충돌 가능성은 작아요.
- 성공한 추론 요청만 응답이 캐시돼요. 요청이 추론 중 실패하거나 오류를 반환하면 그 응답은 캐시되지 않아요.
- 기본 스케줄러(Default Scheduler) 또는 동적 배치 스케줄러(Dynamic Batch Scheduler)를 거치는 요청만 캐싱 자격이 돼요. 시퀀스 배처(Sequence Batcher)는 현재 응답 캐싱을 지원하지 않아요.
- 응답 캐시는 현재 decoupled 모델을 지원하지 않아요.
더 알아보기 (Learn more)
- 모델 구성 (Model Configuration) — response_cache 구성 필드
- 메트릭 (Metrics) — 캐시 적중/미스 메트릭
- 스케줄러 (Schedulers) — 기본·앙상블 스케줄러