# 요청 파라미터의 이해

ChatGPT API를 사용하여 다양한 작업을 수행할 때, 요청 파라미터의 설정은 매우 중요하다. 요청 파라미터는 API가 입력을 어떻게 처리하고, 어떤 방식으로 응답을 생성할지를 제어한다. 이 섹션에서는 주요 요청 파라미터에 대해 상세히 설명하고, 각각의 파라미터가 어떤 역할을 하는지, 그리고 이를 어떻게 최적화할 수 있는지에 대해 다룬다.

#### API 기본 요청 구조

ChatGPT API 요청은 보통 HTTP POST 요청으로 이루어지며, JSON 형식의 페이로드를 포함한다. 기본적인 구조는 다음과 같다.

```python
import openai

response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Can you help me with some information?"}
    ],
    temperature=0.7,
    max_tokens=100
)
```

이 기본적인 예제에서, 우리는 `model`, `messages`, `temperature`, `max_tokens`와 같은 몇 가지 중요한 파라미터를 사용하였다. 이제 이들 파라미터의 역할과 설정 방법을 상세히 살펴보겠다.

#### model

* **설명**: `model` 파라미터는 요청에 사용할 언어 모델을 지정한다. 예를 들어, `gpt-4`는 GPT-4 모델을, `gpt-3.5-turbo`는 GPT-3.5 모델을 의미한다.
* **용도**: 모델의 선택은 응답의 품질과 API 사용 비용에 직접적인 영향을 미친다. 최신 모델일수록 더 나은 성능을 제공하지만, 비용이 더 많이 들 수 있다.
* **예시**:

```python
model="gpt-4"
```

#### messages

* **설명**: `messages` 파라미터는 대화의 맥락을 제공하는 입력 메시지들의 리스트이다. 각 메시지는 `role`과 `content`로 구성된다.
  * `role`: 메시지의 역할을 지정하며, `system`, `user`, `assistant` 중 하나를 가질 수 있다.
  * `content`: 해당 메시지의 실제 내용을 담고 있다.
* **용도**: 이 파라미터는 대화의 흐름을 관리하며, 시스템의 초기 지침을 설정하거나 사용자의 질문, 그리고 이전 대화 내용을 포함할 수 있다.
* **예시**:

```python
messages=[
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "What is the capital of France?"}
]
```

#### temperature

* **설명**: `temperature` 파라미터는 생성되는 텍스트의 창의성을 조절하는 데 사용된다. 이 값은 0과 1 사이의 부동소수점 수로 설정할 수 있다.
  * 값이 높을수록(예: 0.8) 더 창의적이고 다양성 있는 출력을 생성한다.
  * 값이 낮을수록(예: 0.2) 더 집중되고 예측 가능한 출력을 생성한다.
* **용도**: 창의성이 필요한 작업(예: 이야기 생성)에서는 높은 `temperature` 값을, 정확한 답변이 필요한 작업(예: 사실 기반 질문)에서는 낮은 `temperature` 값을 사용하는 것이 일반적이다.
* **수식**: 텍스트 생성 과정에서의 확률 분포는 다음과 같이 표현될 수 있다.

$$
P(w\_i) = \frac{\exp\left(\frac{\log P(w\_i)}{\text{temperature}}\right)}{\sum\_{j} \exp\left(\frac{\log P(w\_j)}{\text{temperature}}\right)}
$$

여기서 $P(w\_i)$는 단어 $w\_i$가 선택될 확률을 나타내며, `temperature` 값이 확률 분포의 집중도에 영향을 준다.

* **예시**:

```python
temperature=0.7
```

#### max\_tokens

* **설명**: `max_tokens` 파라미터는 API가 생성할 수 있는 최대 토큰 수를 지정한다. 여기서 "토큰"은 단어의 조각이나 전체 단어를 나타낼 수 있으며, 모델에 따라 다르게 정의된다.
* **용도**: 생성되는 텍스트의 길이를 제어하는 데 사용된다. 긴 응답이 필요한 경우 이 값을 높이고, 짧은 응답이 필요한 경우 이 값을 낮춘다.
* **수식**: 출력 텍스트 $T$는 다음과 같이 표현될 수 있다.

$$
T = \sum\_{i=1}^{n} t\_i \quad \text{where} \quad n \leq \text{max\_tokens}
$$

여기서 $t\_i$는 개별 토큰을 의미하며, 총합 $T$의 길이는 `max_tokens`를 초과할 수 없다.

* **예시**:

```python
max_tokens=100
```

#### top\_p

* **설명**: `top_p` 파라미터는 Nucleus Sampling(핵심 샘플링) 기법을 사용하여 텍스트 생성을 제어한다. `top_p`는 확률의 누적 합계가 `top_p` 이상이 될 때까지 후보 단어를 포함한다.
  * `top_p=1.0`은 nucleus sampling을 사용하지 않음을 의미하며, 모든 후보 단어가 고려된다.
  * `top_p=0.9`은 상위 90%의 확률 질량을 차지하는 단어들만 고려한다.
* **용도**: 이 파라미터는 모델의 출력을 더욱 다양하게 만들 수 있으며, 특정 응답 유형을 선호하는 데 도움이 된다.
* **수식**: 텍스트 생성 시 후보 단어들의 누적 확률은 다음과 같다.

$$
\sum\_{i=1}^{k} P(w\_i) \geq \text{top\_p}
$$

여기서 $k$는 선택된 단어의 수를 나타내며, 총합이 `top_p` 이상이 되면 후보 선택이 종료된다.

* **예시**:

```python
top_p=0.9
```

#### presence\_penalty

* **설명**: `presence_penalty`는 모델이 새로운 주제를 도입하는 빈도를 증가시키거나 감소시키는 데 사용된다. 값이 양수일 경우 새로운 주제를 도입하는 경향이 증가하고, 음수일 경우 감소한다.
* **용도**: 대화의 다양성을 높이거나 특정 주제에 대한 집중도를 조절할 때 유용하다.
* **수식**: 각 단어의 로그 확률 $\log P(w\_i)$에 가중치를 적용하여 계산된다.

$$
\log P(w\_i) = \log P(w\_i) + (\text{presence\_penalty})
$$

* **예시**:

```python
presence_penalty=0.6
```

#### frequency\_penalty

* **설명**: `frequency_penalty`는 동일한 단어가 반복되는 빈도를 제어한다. 양수 값은 반복을 줄이고, 음수 값은 반복을 허용하는 경향이 있다.
* **용도**: 특정 단어의 반복을 피하고자 할 때 사용된다.
* **수식**: 반복 단어에 대해 로그 확률이 페널티를 받는다.

$$
\log P(w\_i) = \log P(w\_i) - (\text{frequency\_penalty} \times \text{count}(w\_i))
$$

* **예시**:

```python
frequency_penalty=0.5
```

#### stop

* **설명**: `stop` 파라미터는 생성된 텍스트를 멈추게 하는 문자열 또는 문자열 목록을 지정한다. 모델은 이 문자열을 만나면 추가 텍스트 생성을 중단한다.
* **용도**: 특정 구문이나 문장이 나타날 때 응답을 종료하고자 할 때 유용하다. 예를 들어, 대화형 응답에서 문장이 너무 길어지지 않도록 할 때 사용할 수 있다.
* **예시**:

```python
stop=["\n", "User:"]
```

위의 예시는 줄바꿈 문자나 "User:" 문자열을 만나면 텍스트 생성을 멈추도록 설정한다.

#### logit\_bias

* **설명**: `logit_bias` 파라미터는 특정 토큰의 선택 확률을 수정하는 데 사용된다. 토큰의 ID와 그에 대한 가중치를 매핑하여, 모델이 특정 토큰을 더 자주 또는 덜 자주 선택하도록 강제할 수 있다.
* **용도**: 특정 단어를 억제하거나 선호할 때 사용된다. 예를 들어, 부정적인 단어의 사용을 줄이거나 특정 키워드를 강조할 수 있다.
* **수식**: 각 토큰 $t\_i$의 로그 확률 $\log P(t\_i)$는 다음과 같이 수정된다.

$$
\log P(t\_i) = \log P(t\_i) + \text{logit\_bias}(t\_i)
$$

여기서 `logit_bias(t_i)`는 토큰 $t\_i$에 적용되는 바이어스를 나타낸다.

* **예시**:

```python
logit_bias={50256: -100}  # 특정 토큰의 확률을 사실상 0으로 만듦
```

#### n

* **설명**: `n` 파라미터는 각 요청에서 생성할 응답의 개수를 지정한다. 하나의 요청에 대해 여러 개의 응답을 받아 다양한 출력을 비교할 수 있다.
* **용도**: 모델의 출력을 샘플링하여 다양한 응답을 생성하고자 할 때 유용하다. 여러 개의 응답을 받은 후, 그 중에서 가장 적합한 것을 선택할 수 있다.
* **수식**: 생성된 응답의 개수는 다음과 같이 표현된다.

$$
\text{Number of responses} = n
$$

* **예시**:

```python
n=3
```

#### stream

* **설명**: `stream` 파라미터는 응답을 스트리밍 방식으로 받을지를 결정한다. `stream=True`로 설정하면 응답이 생성되는 대로 실시간으로 전달된다.
* **용도**: 응답이 긴 경우 전체 응답을 기다리지 않고 부분적으로 처리할 수 있어, 사용자에게 더 빠른 피드백을 제공할 수 있다.
* **예시**:

```python
stream=True
```

#### user

* **설명**: `user` 파라미터는 요청을 보낸 사용자의 식별자를 지정할 수 있는 필드이다. 이 정보는 사용자 맞춤형 로그 및 분석을 위해 사용될 수 있다.
* **용도**: 다중 사용자 환경에서 각 사용자의 요청을 식별하고, 사용자별로 응답을 최적화할 때 유용하다.
* **예시**:

```python
user="user-1234"
```

#### stream과 비동기 처리

`stream=True` 옵션을 사용하면, 응답을 실시간으로 수신할 수 있다. 이때 비동기 처리 방식으로 API 호출을 관리하는 것이 중요하다. Python에서는 `asyncio` 모듈을 사용하여 비동기 API 호출을 쉽게 처리할 수 있다.

```python
import openai
import asyncio

async def generate_response():
    response = await openai.ChatCompletion.acreate(
        model="gpt-4",
        messages=[
            {"role": "user", "content": "Tell me a story."}
        ],
        stream=True
    )
    
    async for chunk in response:
        print(chunk['choices'][0]['delta'].get('content', ''), end='')

asyncio.run(generate_response())
```

위 코드에서는 `stream=True`로 설정된 API 호출이 비동기적으로 처리되며, 응답이 부분적으로 전달될 때마다 출력된다.

#### 다양한 파라미터의 조합

이제까지 다룬 여러 파라미터들을 적절히 조합하여, 모델의 출력을 최적화할 수 있다. 예를 들어, `temperature`와 `top_p`를 함께 조정하거나, `frequency_penalty`와 `presence_penalty`를 결합하여 텍스트의 반복성과 다양성을 동시에 관리할 수 있다.

* 예를 들어, 다음과 같은 설정을 사용해 볼 수 있다.

```python
response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Write a creative story."}],
    temperature=0.85,
    max_tokens=150,
    top_p=0.95,
    frequency_penalty=0.5,
    presence_penalty=0.6
)
```

이 조합은 창의적이고 다양한 이야기를 생성하지만, 동일한 표현의 반복을 줄이고 새로운 주제를 도입할 가능성을 높인다.
