SambaNova 텍스트 생성 (추론)

SambaNova 텍스트 생성 (추론)

텍스트 생성은 SambaNova 추론의 핵심 기능이에요. 단순 생성부터 스트리밍, 비동기 호출까지 방식이 다양하고, 모델 선택과 프롬프트 구성, 여러 차례의 대화를 이어가는 방법까지 함께 다뤄요. ChatGPT 같은 채팅 애플리케이션을 만들 때 필요한 대부분의 요소가 이 페이지에 담겨 있어요.

출처: 텍스트 생성 기능 구현

생성 방식

단순 생성 (비스트리밍)

SambaNova SDK나 OpenAI 클라이언트로 요청을 보내고 응답이 완전히 끝난 뒤 결과를 받는 방식이에요.

from sambanova import SambaNova
client = SambaNova(
    base_url="your-sambanova-base-url",
    api_key="your-sambanova-api-key"
)
completion = client.chat.completions.create(
    model="Meta-Llama-3.3-70B-Instruct",
    messages = [
        {"role": "system", "content": "Answer the question in a couple sentences."},
        {"role": "user", "content": "Share a happy story with me"}
    ]
)
print(completion.choices[0].message.content)
from openai import OpenAI
client = OpenAI(
    base_url="your-sambanova-base-url",
    api_key="your-sambanova-api-key"
)
completion = client.chat.completions.create(
    model="Meta-Llama-3.3-70B-Instruct",
    messages = [
        {"role": "system", "content": "Answer the question in a couple sentences."},
        {"role": "user", "content": "Share a happy story with me"}
    ]
)
print(completion.choices[0].message.content)

비동기 생성 (비스트리밍)

동시에 여러 작업을 처리하고 싶다면 AsyncSambaNova 또는 AsyncOpenAI 클라이언트를 써요.

from sambanova import AsyncSambaNova
import asyncio
async def main():
    client = AsyncSambaNova(
        base_url="your-sambanova-base-url",
        api_key="your-sambanova-api-key"
    )
    completion = await client.chat.completions.create(
        model="Meta-Llama-3.3-70B-Instruct",
        messages = [
            {"role": "system", "content": "Answer the question in a couple sentences."},
            {"role": "user", "content": "Share a happy story with me"}
        ]
    )
    print(completion.choices[0].message.content)
asyncio.run(main())
from openai import AsyncOpenAI
import asyncio
async def main():
    client = AsyncOpenAI(
        base_url="your-sambanova-base-url",
        api_key="your-sambanova-api-key"
    )
    completion = await client.chat.completions.create(
        model="Meta-Llama-3.3-70B-Instruct",
        messages = [
            {"role": "system", "content": "Answer the question in a couple sentences."},
            {"role": "user", "content": "Share a happy story with me"}
        ]
    )
    print(completion.choices[0].message.content)
asyncio.run(main())

스트리밍 응답

실시간으로 토큰을 이어 받고 싶으면 stream = True를 켜요. 응답이 통째로 오기 전에 한 조각씩 출력돼요.

from sambanova import SambaNova
client = SambaNova(
    base_url="your-sambanova-base-url",
    api_key="your-sambanova-api-key"
)
completion = client.chat.completions.create(
    model="Meta-Llama-3.3-70B-Instruct",
    messages = [
        {"role": "system", "content": "Answer the question in a couple sentences."},
        {"role": "user", "content": "Share a happy story with me"}
    ],
    stream = True
)
for chunk in completion:
  print(chunk.choices[0].delta.content, end="")

스트리밍 모드에서는 각 청크에 여러 토큰이 함께 담길 수 있어요. 초당 토큰수(tokens per second) 같은 지표를 계산할 때는 청크 안의 모든 토큰을 세어야 해요.

여러 개의 완성 생성하기

n 파라미터로 하나의 프롬프트에 대해 여러 개의 독립적인 응답을 만들 수 있어요. 결과는 choices[0]부터 choices[n-1]까지 담겨요.

파라미터 타입 기본값 유효 범위
n integer 1 1–8

temperature를 0보다 크게 설정해야 응답 간에 차이가 나요. temperature: 0이면 모든 응답이 동일해져요. 그리고 n이 1보다 크면 함수 호출(function calling)이나 툴과 함께 쓸 수 없어요 — 함께 쓰면 400 에러가 돌아와요.

from sambanova import SambaNova

client = SambaNova(
    base_url="your-sambanova-base-url",
    api_key="your-sambanova-api-key"
)

completion = client.chat.completions.create(
    model="Meta-Llama-3.1-8B-Instruct",
    messages=[
        {"role": "user", "content": "Write a one-sentence tagline for a coffee shop."}
    ],
    n=3,
    temperature=0.7
)

for i, choice in enumerate(completion.choices):
    print(f"Completion {i + 1}: {choice.message.content}")

이 동작은 SambaCloud와 SambaStack 모두에 적용돼요.

모델 선택

모델마다 아키텍처가 달라서 속도와 응답 품질이 달라져요. 모델을 고를 때는 다음 요소를 함께 봐요.

요소 고려할 점
작업 복잡도 복잡한 작업일수록 큰 모델이 유리해요.
정확도 요구 일반적으로 큰 모델이 정확도가 높아요.
비용과 리소스 큰 모델일수록 비용과 리소스 요구량이 늘어나요.

여러 모델을 실험해 보고 자신의 유스케이스에 가장 잘 맞는 모델을 고르는 게 좋아요.

효과적인 프롬프트 만들기

프롬프트 엔지니어링은 LLM의 응답을 최적화하도록 프롬프트를 설계·다듬는 작업이에요. 반복적인 실험이 필요한 과정이에요.

기본 프롬프트 구성

단순한 프롬프트는 몇 마디로 끝나지만, 복잡한 유스케이스라면 다음 요소가 필요할 수 있어요.

요소 설명
페르소나 정의 모델에 역할을 부여해요 (예: "You are a financial advisor").
맥락 제공 응답을 유도하는 배경 정보를 넣어요.
출력 형식 지정 JSON, 불릿, 구조화 텍스트 등 특정 스타일을 요구해요.
유스케이스 설명 상호작용의 목표를 명확히 해요.

고급 프롬프팅 기법

응답 품질과 추론을 높이려면 다음 기법을 쓸 수 있어요.

기법 설명
인컨텍스트 러닝 (In-context learning) 원하는 출력의 예시를 넣어 모델을 유도해요.
Chain-of-Thought (CoT) 프롬프팅 답을 내기 전에 추론 과정을 먼저 말하도록 유도해요.

메시지와 역할

채팅 상호작용에서 메시지는 특정 rolecontent를 가진 딕셔너리로 표현돼요.

요소 설명
role 누가 메시지를 보내는지 지정해요.
content 메시지 본문 텍스트예요.

주로 쓰는 역할은 system, user, assistant예요.

역할 설명
system 모델에 전반적인 지시를 줘요.
user 사용자 입력을 나타내요.
assistant 모델의 응답을 담아요.
tool 툴 실행 결과를 담아요.

멀티턴 대화

여러 차례에 걸쳐 맥락을 유지하려면 메시지를 딕셔너리 리스트로 관리해요. Meta-Llama-3.3-70B-Instruct로 구성한 예시예요.

completion = client.chat.completions.create(
    model="Meta-Llama-3.3-70B-Instruct",
    messages = [
        {"role": "user", "content": "Hi! My name is Peter and I am 31 years old. What is 1+1?"},
        {"role": "assistant", "content": "Nice to meet you, Peter. 1 + 1 is equal to 2"},
        {"role": "user", "content": "What is my age?"}
    ],
    stream = True
)
for chunk in completion:
  print(chunk.choices[0].delta.content, end="")

이렇게 하면 모델이 이전 맥락을 기억해서 "You told me earlier, Peter. You're 31 years old." 같은 답을 내놓아요.

대화가 길어질 때 주의할 점

  • 토큰 한도 — LLM은 정해진 컨텍스트 창을 갖고 있어요. 입력이 한도를 넘으면 잘릴 수 있고, 응답이 불완전해질 수 있어요.
  • 메모리 제약 — 모델은 입력 창 밖의 맥락을 기억하지 못해요. 과거 메시지를 프롬프트에 다시 포함시켜야 해요.

DeepSeek-V3.2 씽킹 모드

DeepSeek-V3.2는 선택적으로 씽킹 모드(thinking mode)를 지원해요. 최종 응답 앞에 모델의 추론을 `thinking` 태그 안에 담아 출력해요. 기본은 비활성이고, 요청에 chat_template_kwargsenable_thinkingtrue로 넘기면 켜져요.

curl -X POST https://your-sambastack-url/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "DeepSeek-V3.2",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant"},
      {"role": "user", "content": "Explain how photosynthesis works."}
    ],
    "chat_template_kwargs": {"enable_thinking": true}
  }'

씽킹 모드가 켜지면 응답 내용이 `thinking` 태그의 추론으로 시작하고, 그 뒤에 최종 답변이 이어져요. 이 기능은 DeepSeek-V3.2의 CB(continuous batching) 번들 배포에서만 쓸 수 있어요.

Gemma 4 31B 씽킹 모드

gemma-4-31B-it도 선택적 씽킹 모드를 지원해요. 최종 응답과 함께 별도의 reasoning 필드에 추론을 담아요. 이 역시 기본 비활성이고 chat_template_kwargsenable_thinkingtrue로 넘기면 켜져요.

Gemma 4 31B는 씽킹 모드와 함께 툴 호출을 쓸 수 있어요. 둘 다 켜면 모델이 문제를 추론하고, 같은 응답 안에 툴 호출 결정을 담아 돌려줘요.

주의할 점이 하나 있어요. reasoning 필드는 대화 히스토리에 다시 포함되지 않아요. 멀티턴 대화에서 모델은 자신의 이전 추론에 접근하지 못하니, 이후 턴에서 이전 추론이 남아 있다고 가정하면 안 돼요.

curl -X POST https://your-sambastack-url/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemma-4-31B-it",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant"},
      {"role": "user", "content": "Compare the trade-offs between using a relational database and a document store for a high-write e-commerce workload."}
    ],
    "chat_template_kwargs": {"enable_thinking": true}
  }'

씽킹 모드가 켜지면 응답에는 모델 사고 과정을 담은 reasoning 필드와 함께 최종 답인 content가 들어와요. 툴 호출도 함께 쓰는 경우 contentnull이 되고, reasoningtool_calls에 모델의 결정이 담겨요.

{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": null,
        "reasoning": "The user wants me to call a tool to get the integer 7. ...",
        "role": "assistant",
        "tool_calls": [
          {
            "function": {
              "arguments": "{\"value\":7}",
              "name": "return_integer"
            },
            "id": "call_92ad8c74a4594172b6",
            "type": "function"
          }
        ]
      }
    }
  ],
  "id": "42d3a6ac-d984-40b1-9389-f5af73cb599e",
  "model": "gemma-4-31B-it",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 74,
    "prompt_tokens": 91,
    "total_tokens": 165
  }
}

더 알아보기 (Learn more)