OVERVIEW GPU 텍스트 생성 개요

EXAONE-4.0-1.2B 모델을 활용한 한국어 텍스트 생성 API입니다. 비동기 큐 방식으로 동작하며, 요청 즉시 request_id를 반환하고 완료 후 결과를 조회합니다.

OpenAI 호환 엔드포인트도 사용 가능: POST /v1/chat/completions (Bearer 또는 X-API-Key 인증, messages·stream=true SSE 지원). OpenAI Python SDK · LangChain · OpenWebUI 등에서 base_url만 RedGX로 변경하면 호출 가능. 자세한 내용은 메인 튜토리얼 OpenAI 호환 섹션 참고.
요청 추적: X-Request-ID 헤더를 보내면 응답 헤더로 echo + 모든 로그(audit 포함)에 자동 주입됩니다. 미전송 시 RedGX가 UUID4 hex(32자)를 자동 생성.
LG AI EXAONE-4.0-1.2B — LG AI Research가 개발한 한국어 특화 대규모 언어 모델. 1.2B 파라미터의 경량 모델이면서도 한국어 이해·생성에서 GPT-3.5급 성능을 보입니다. 요약, 질의응답, 문서 작성, 코드 생성 등 다양한 태스크를 지원합니다. vLLM으로 서빙하여 PagedAttention과 Continuous Batching으로 효율적으로 동작합니다. FP16 기준 VRAM ~2.4GB로 RTX 3060에서 단독 운영 가능합니다.
아키텍처 흐름
# 1. POST → 202 Accepted (request_id 반환)
POST /api/v1/ns/{ns}/gpu/generate
  → 202 { "request_id": "gen-1710000000000-a1b2c3d4" }

# 2. GET 폴링 → 완료 시 200 (텍스트 결과)
GET /api/v1/ns/{ns}/gpu/generate/{request_id}
  → 202 { "status": "queued" }           # 대기 중202 { "status": "processing" }       # 추론 중 (수 초)200 { "status": "completed", ... }   # 완료!
생성 소요 시간: EXAONE-4.0-1.2B 기준 512 토큰 생성에 약 5~15초 소요됩니다. LLM은 임베딩보다 훨씬 느리므로 폴링 간격을 1~2초로 설정하세요.
모델 정보
항목
모델LGAI-EXAONE/EXAONE-4.0-1.2B
VRAM 사용~2.4GB (RTX 3060 12GB)
특징한국어 특화, Chat Template 지원
캐시temperature = 0.0 일 때만 적용 (동일 입력 → 즉시 반환)
Chunking장문 입력 자동 분할 (Sliding Window)
POST 기본 텍스트 생성

프롬프트를 입력하면 LLM이 텍스트를 생성합니다. 요청 후 완료까지 폴링이 자동으로 수행됩니다.

POST /api/v1/ns/{ns}/gpu/generate
curl 명령 보기

            
POST System Prompt 활용

system_prompt로 AI의 역할과 응답 스타일을 지정합니다. 동일한 질문이라도 시스템 프롬프트에 따라 전혀 다른 응답을 얻을 수 있습니다.

POST system_prompt 포함 요청
curl 명령 보기

            
POST LLM 번역 활용 — 수사 문서 한→영
💡 NMT 대체: NMT 번역 품질이 부족할 때 LLM + system_prompt로 번역을 대체할 수 있습니다. temperature=0.0으로 고정하면 결정론적 출력 및 캐시가 적용됩니다.
0.0 = 결정론적 + 캐시
curl 명령 보기

            
POST LLM 번역 활용 — 장문 청크 분할 번역 (한→영)
💡 장문 청크 분할: 토큰 한계로 단일 요청으로 처리하기 어려운 장문을 문장 경계에서 자동 분할하여 청크별로 순차 번역한 뒤 결과를 병합합니다. NLLB 번역 서버의 내부 청킹 로직(_split_long_text)과 동일한 알고리즘을 클라이언트에서 직접 구현합니다.
문장 경계 기준 분할
POST Temperature 비교

temperature는 생성의 창의성을 제어합니다. 0.0은 결정론적(항상 같은 답), 높을수록 다양하고 창의적인 응답을 생성합니다.

💡 권장값: 요약·번역·정보 추출 → 0.0~0.3  |  일반 대화 → 0.5~0.7  |  창의적 글쓰기 → 0.8~1.2
동일 프롬프트, 다른 temperature로 3회 비교
curl 명령 보기

            
POST 결과 캐시 (temperature = 0.0)

temperature=0.0으로 동일한 요청을 두 번 보내면, 두 번째는 캐시에서 즉시 반환됩니다. temperature > 0이면 캐시가 적용되지 않습니다 (결과가 매번 다를 수 있으므로).

1회차 → 2회차 캐시 적중 확인
🔒 0.0 고정 — 캐시가 적용되는 유일한 조건
1·2회차 동일값 유지 필수
curl 명령 보기

            
POST Sliding Window Chunking

입력이 모델의 최대 토큰 수를 초과하면 자동으로 청크로 분할하여 처리합니다. 각 청크는 순차적으로 추론되고 결과가 병합됩니다.

EXAONE-4.0-1.2B: max_input_tokens 기본값 4096, context 65K 지원. 이 테스트는 chunking_enabled=true를 명시적으로 전달합니다. 짧은 입력에서도 동작 확인이 가능합니다.
Merge 전략 (서버 설정): config/gpu_relay.yamltasks.generation.chunking.merge_strategy로 결정합니다.
  • concatenate (기본) — 각 청크 결과를 순서대로 이어붙임. 보고서·요약처럼 누적되는 출력에 적합.
  • last_only — 마지막 청크 결과만 사용. Q&A처럼 마지막 컨텍스트가 정답인 경우.
Sliding window overlap은 overlap_ratio(기본 0.15, 범위 0.0~0.5)로 조정 — 청크 경계 컨텍스트 손실 방지.
Chunking 요청
curl 명령 보기

            
MANAGE 결과 관리 — 조회 / 삭제 / 취소

결과는 outbox에 1시간(3600초) 보관됩니다. GET으로 조회하거나 DELETE로 즉시 삭제할 수 있습니다. 대기 중인 요청은 cancel로 취소 가능합니다.

GET 결과 조회
curl 명령 보기

            
DELETE 결과 삭제
curl 명령 보기

            
POST 요청 취소
큐에 대기 중인 요청만 취소 가능합니다. 이미 처리 중이면 409 응답이 반환됩니다.
curl 명령 보기

            
POST 배치 상태 일괄 조회

여러 request_id의 상태를 한 번의 API 호출로 조회합니다.

POST /gpu/generate/batch-status
curl 명령 보기

            
ERROR 에러 케이스

인증 실패, 잘못된 파라미터, 비활성 태스크 등 다양한 에러 상황을 테스트합니다.

REF API 레퍼런스
POST /api/v1/ns/{ns}/gpu/generate — 요청 파라미터
필드타입기본값설명
promptstring필수생성할 텍스트 프롬프트
system_promptstring | nullnull시스템 역할 지시문
modelstring | null서버 기본값사용할 모델명 (null = 서버 설정값)
max_new_tokensint | null서버 기본값최대 생성 토큰 수 (1~8192)
temperaturefloat0.7샘플링 온도 (0.0~2.0, 0.0=greedy)
chunking_enabledbool | null서버 설정값Sliding Window 청킹 활성화 여부
GET 완료 응답 구조 (HTTP 200)
{
  "ok": true,
  "data": {
    "request_id": "gen-1710567890123-a1b2c3d4",
    "status":     "completed",
    "output_text": "생성된 텍스트...",
    "model":       "LGAI-EXAONE/EXAONE-4.0-1.2B",
    "chunk_count": 1,
    "input_tokens": 42,
    "output_tokens": 128,
    "cached":      false,
    "elapsed_ms":  8432.5
  }
}
필드설명
request_id요청 ID
statuscompleted 또는 failed
output_text생성된 텍스트 (청킹 시 병합 결과)
model실제 사용된 모델명
chunk_count처리된 청크 수 (1 = 청킹 없음)
input_tokens입력 토큰 수 (청킹 시 null)
output_tokens출력 토큰 수 (청킹 시 null)
cached캐시 적중 여부 (temperature=0.0 일 때만 적용)
elapsed_ms전체 처리 시간 (ms)
chunks청크별 상세 결과 배열 (chunk_count > 1 시, 각 항목: chunk_index, chunk_count, input_tokens, output_text)
에러 코드
코드HTTP설명
UNAUTHORIZED401API Key 누락 또는 잘못됨
NAMESPACE_DENIED403Namespace 접근 권한 없음
GPU_TASK_DISABLED503generation 태스크 비활성 상태 (REDGX_GPU_GENERATION_ENABLED=false)
GPU_UNAVAILABLE503CUDA 불가 또는 모델 미로드
GPU_QUEUE_FULL503큐 용량 초과 (max_inflight 또는 max_requests 도달)
GPU_PROCESSING409취소 불가 — 이미 처리 중
GPU_NOT_FOUND404Request ID 없음 또는 만료 (outbox TTL 3600s)
422파라미터 유효성 오류 (빈 prompt, max_new_tokens > 8192 등) — FastAPI 기본 형식: {"detail":[...]}, error.code 없음
429nginx Rate Limit 초과 (IP당 10 r/s, burst 20). 응답은 plain HTML, JSON 코드 없음
WS /api/v1/ns/{ns}/gpu/generate/{req_id}/wait — 결과 Push 대기

Redis Pub/Sub으로 완료 알림을 수신 후 즉시 결과를 전송합니다. LLM은 처리 시간이 길어 GET 폴링보다 이 방식이 적합합니다.

// 인증: Sec-WebSocket-Protocol 헤더로 API 키 전달 (URL 쿼리 미지원)
// 브라우저: new WebSocket(url, ["redgx_ak_hrm_..."])
wss://<host>/api/v1/ns/HRM/gpu/generate/gen-xxx/wait?timeout=120          // LLM은 최대 120s 권장
// 완료 — REST GET과 동일 구조
{ "ok": true, "data": { "request_id": "gen-...", "status": "completed",
    "output_text": "생성된 텍스트", "model": "LGAI-EXAONE/EXAONE-4.0-1.2B",
    "chunk_count": 1, "input_tokens": 42, "output_tokens": 128,
    "cached": false, "elapsed_ms": 3200.0 } }

// 실패
{ "ok": true, "data": { "request_id": "gen-...", "status": "failed", "error": {...} } }

// 인증 실패 → HTTP 403 (upgrade 거부, accept 전 — 4001 close 프레임 미전송)
// Not Found    → { "ok": false, "error": { "code": "GPU_NOT_FOUND" } } + close(4004)
// Timeout      → { "ok": false, "error": { "code": "GPU_TIMEOUT" } }  + close(4008)