Skip to content

실전 예제를 상징하는 이미지

이 주제의 마지막 글은 복사해서 바로 써도 되는 요청 모음이다. 전부 공식 GUIDE §5의 예제를 따른 것이고, 일부 응답 필드와 주의점을 한국어로 보탰다.

준비 ​

서버를 띄우고(기동 플래그는 모델마다 다르다 — README 표 참고) 헬스체크부터.

sh
radiance --model /srv/models/rad/qwen3.8-27b-fp8.rad --tp 2 --port 8000
curl -s localhost:8000/health

아래 예제는 API 키 없이 띄운 로컬 서버 기준이다. --api-key를 썼다면 모든 요청에 Authorization: Bearer $KEY를 붙이면 된다(예외: /health, /ping, 대시보드 페이지).

텍스트: 채팅, 스트리밍, 도구, JSON ​

sh
# 기본 채팅
curl -s localhost:8000/v1/chat/completions -H 'Content-Type: application/json' -d '{
  "model": "m",
  "messages": [{"role": "user", "content": "Explain merge sort briefly."}],
  "max_tokens": 200, "temperature": 0.7
}' | jq -r '.choices[0].message.content'

# 스트리밍 (SSE, data: [DONE]로 끝남)
curl -N localhost:8000/v1/chat/completions -H 'Content-Type: application/json' -d '{
  "model":"m","messages":[{"role":"user","content":"Count to ten."}],
  "max_tokens":100,"stream":true,"stream_options":{"include_usage":true}}'

# thinking 끄기 / 합산 금지 — reasoning_content로 분리돼 온다
-d '{"...":"...","reasoning_effort":"none"}'

도구 호출은 OpenAI 규격 그대로이고 결과는 message.tool_calls, finish_reason: "tool_calls"다.

sh
curl -s localhost:8000/v1/chat/completions -H 'Content-Type: application/json' -d '{
  "model": "m",
  "messages": [{"role":"user","content":"What is in /etc/hosts?"}],
  "tools": [{"type": "function", "function": {
      "name": "read", "description": "read a file",
      "parameters": {"type":"object","properties":{"path":{"type":"string"}},"required":["path"]}}}],
  "tool_choice": "auto", "max_tokens": 300
}' | jq '.choices[0].message.tool_calls'

제약 출력 세 가지 — JSON 객체, JSON 스키마, GBNF. 스키마는 실제 문법이 되어 호출을 강제한다(7편 참조: 채팅 템플릿이 제약을 삼키면 요청이 거부된다).

sh
-d '{"model":"m","messages":[...],"response_format":{"type":"json_object"}}'
-d '{"model":"m","prompt":"...","grammar":"root ::= \"yes\" | \"no\""}'

이미지 생성과 편집 ​

이미지 모델(Qwen-Image, FLUX.3 [klein], Krea 2, SDXL…)이 켜진 서버에서는:

sh
# 생성 — 기본 2048x2048, b64_json으로 돌아온다
curl -s localhost:8000/v1/images/generations -H 'Content-Type: application/json' \
  -d '{"prompt":"a lighthouse on a cliff at sunset, oil painting","size":"1024x1024"}' \
  | python3 -c 'import sys,json,base64; open("out.png","wb").write(base64.b64decode(json.load(sys.stdin)["data"][0]["b64_json"]))'

# 편집 — OpenAI SDK가 보내는 multipart, 마스크는 투명한 부분만 다시 그림
curl -s localhost:8000/v1/images/edits -F image=@photo.png -F mask=@mask.png \
  -F prompt="repaint the sky at dusk"

"partial_images"를 주면 SSE로 진행률 프리뷰가 먼저 온다. Qwen-Image 2.1은 연구 라이선스(비상업)라는 점을 README가 명시한다.

임베딩과 토큰 ​

sh
curl -s localhost:8000/v1/embeddings -H 'Content-Type: application/json' -d '{"model":"m","input":"hello"}'
curl -s localhost:8000/tokenize -H 'Content-Type: application/json' \
  -d '{"messages":[{"role":"user","content":"hi"}]}'   # 채팅 템플릿 적용 결과와 개수

임베딩 모델은 EmbeddingGemma 2(텍스트·이미지·비디오·오디오), nomic-embed, Nemotron Embed/Rerank. prompt_name으로 체크포인트의 named prompt("query" 등)를 쓸 수 있고, 접두어 붙이기는 클라이언트 몫이다.

음성 합성, 목소리 복제, 음악 ​

sh
# Breeze-TTS-2: 지시로 목소리 묘사, 24kHz 모노 WAV
curl -s localhost:8000/v1/audio/speech -H 'Content-Type: application/json' -d '{
  "input": "It was a bright cold day in April.",
  "instructions": "A calm, warm female narrator, speaking slowly.", "guidance_scale": 4
}' -o april.wav

# drama-3: 화자 태그와 지시를 입력에, 참조 클립으로 목소리 복제 (44.1kHz)
curl -s localhost:8000/v1/audio/speech -H 'Content-Type: application/json' -d @- -o door.wav <<'EOF'
{"input": "<|speaker:0|> Did you lock the back door?\n<|speaker:1|> [sighs] I thought you did.",
 "references": [{"audio": "<voice.wav의 base64>", "text": "클립이 한 말"}]}
EOF

# MiniMax-Music3: input=가사, instructions=곡 설명
curl -s localhost:8000/v1/audio/speech -H 'Content-Type: application/json' -d '{
  "input": "[verse]\nMorning light filtering through the pine\n[chorus]\nSoftly the world begins to breathe",
  "instructions": "Genre: acoustic pop. BPM: 96. Warm and intimate. Vocals: soft female lead.",
  "duration": 30, "seed": 7}' -o song.wav

실시간에 가까운 합성 속도가 실측되어 있다(Breeze는 재생 시간의 0.6배, drama-3는 0.3배). 텍스트를 써지는 동시에 문장별로 읽는 /v1/audio/speech/stream WebSocket도 있다. seed를 주면 같은 곡·같은 낭독이 재현된다(응답 헤더 X-Seed).

음성 인식과 라이브 전사 ​

Qwen3-ASR은 OpenAI 전사 API를 그대로 답한다. 30초 인코더 패스보다 긴 녹음은 자동으로 조용한 지점에서 잘려 이어진다(최대 1시간).

sh
curl -s localhost:8000/v1/audio/transcriptions -F file=@meeting.wav -F model=qwen3-asr
curl -s localhost:8000/v1/audio/transcriptions \
  -F file=@clip.mp3 -F language=ko -F response_format=verbose_json   # 언어·구간 타임스탬프 포함

라이브는 OpenAI realtime 프로토콜 WebSocket /v1/realtime — session.update → input_audio_buffer.append(16비트 PCM) → commit → 확정된 문장별 전사를 받는다. OpenAI용으로 작성한 클라이언트가 그대로 붙는다.

비디오 생성 작업 ​

비디오는 백그라운드 작업(OpenAI /v1/videos)이다. MiniMax-H3/FastH3/LTX-2.5 서버에서:

sh
curl -s localhost:8000/v1/videos -H 'Content-Type: application/json' -d '{
  "prompt": "A red fox trotting through a snowy pine forest, snow crunching underfoot",
  "seconds": "5", "size": "1344x768", "seed": 7}'      # {"id": "video_...", "status": "queued"}
curl -s localhost:8000/v1/videos/video_...              # status/progress 폴링
curl -s localhost:8000/v1/videos/video_.../content -o fox.mp4   # H.264 + AAC(스테레오 사운드트랙)

# LTX-2.5: 첫 프레임 지정 (image-to-video)
curl -s localhost:8000/v1/videos -F 'prompt=the fox turns and runs into the trees' \
  -F 'size=768x512' -F 'seconds=5' -F 'input_reference=@fox.png'

seed로 재현되고, MiniMax-H3는 키프레임(first/last frame)과 참조 이미지·영상도 받으며 latent_upscale: 2로 하프 크기에서 시작해 후반만 풀 사이즈로 다듬어 시간을 크게 줄일 수 있다(1344x768 5초 클립: FastH3 약 68초). MiniMax-H3 라이선스는 EU·영국·한국·미국 사용을 별도 계약 대상으로 둠에 주의.

Anthropic 클라이언트 붙이기 ​

Anthropic Messages API도 같은 서버가 답한다 — Claude Code 등 SDK는 base URL만 radiance 쪽으로 바꾸면 된다.

sh
curl -s localhost:8000/v1/messages -H 'Content-Type: application/json' -H 'x-api-key: none' \
  -H 'anthropic-version: 2023-06-01' \
  -d '{"model":"m","max_tokens":100,"messages":[{"role":"user","content":"hello"}]}'

작업이 끝난 뒤에는 /diagnostics의 findings를 한 번 훑는 습관이 좋다. 카드 링크, 전압, cgroup까지 다시 재어 경고와 해법을 정리해 준다(운영 지표 읽기는 GUIDE §6, 대시보드 글 참조). 여기까지가 radiance 주제의 전체 흐름이다 — 설계를 읽고, rig를 준비하고, 모델을 올리고, API로 쓰고, 예산을 조정하고, 필요하면 플러그인으로 확장하는 길.

오픈소스를 한국어로 읽고 배웁니다.