Published on

Ollama Parameters Setting

Authors

ChatGPT 가 완전 대중화되면서 OPENAI의 API를 기반으로 한 예제가 많은데, Ollama와 같은 로컬친화적인 LLM에 대한 UseCase가 아직 많지 않습니다.

LLM을 비롯한 AI에서 파라미터 조절은 다양한 상황에 AI를 사용하기 위한 필수 작업입니다.

Ollama 를 Langchain의 LLM으로 사용하면서 파라미터 조절하는 방법과 그에 해당하는 세팅을 Bind 하는 방법을 기록합니다.

Ollama parameter

Ollama 는 기본적으로 Modelfile 이라는 파일기반의 세팅을 지원(문서의 표현을 빌리면 Blueprint; 청사진, 설계도)합니다.

이 세팅 값을 통해서 model 자체를 build 할때 편하게 커스텀 할 수도있고, 문서에 나와있는 parameter들을 조절해서 Langchain에서 LLM(like Ollama)을 세밀하게 조절할 수 도 있습니다.

Ollama Parameter Description

(하단 문서 참고)

자주 사용하게될 파라미터는 temperature(창의정도) 와 num_predict(토큰 수) 정도가 될 것 같습니다.

  1. mirostat
    • 텍스트의 난해함(혼란도, perplexity)을 조절하기 위해 Mirostat 샘플링을 활성화합니다.
      • 기본값: 0 (0 = 비활성화, 1 = Mirostat, 2 = Mirostat 2.0)
  2. mirostat_eta
    • 알고리즘이 생성된 텍스트의 피드백에 얼마나 빨리 반응할지 결정합니다. 값이 낮으면 조정이 느리고, 높으면 빠릅니다.
      • 기본값: 0.1
  3. mirostat_tau
    • 출력 텍스트의 일관성과 다양성 사이의 균형을 조절합니다. 값이 낮을수록 더 집중적이고 일관된 텍스트를 생성합니다.
      • 기본값: 5.0
  4. num_ctx
    • 다음 토큰을 생성할 때 사용할 문맥 창의 크기를 설정합니다.
      • 기본값: 2048
  5. num_gqa
    • 트랜스포머 레이어에서 사용할 GQA 그룹 수를 설정합니다. 특정 모델에 필요합니다. (llama2:70b 모델에서는 8로 설정.)
      • 기본값: 1
  6. num_gpu
    • GPU에 보낼 레이어 수를 설정합니다. macOS에서는 기본값이 1로 설정되어 메탈 지원이 활성화됩니다. 0으로 설정하면 비활성화됩니다.
      • 기본값: 50
  7. num_thread
    • 계산에 사용할 스레드 수를 설정합니다. 기본적으로 Ollama가 시스템의 물리적 CPU 코어 수를 감지하여 최적 성능을 설정합니다.
      • 기본값: 8
  8. repeat_last_n
    • 반복을 방지하기 위해 모델이 얼마큼 과거로 돌아가서 문맥을 참조할지 설정합니다.
      • 기본값: 64 (0 = 비활성화, -1 = num_ctx와 동일)
  9. repeat_penalty
    • 반복되는 단어를 얼마나 강하게 억제할지 설정합니다. 값이 높을수록 반복을 더 강하게 억제합니다.
      • 기본값: 1.1
  10. 💫temperature
    • 모델의 창의성을 조절합니다. 값이 높을수록 더 창의적이고 예측 불가능한 응답이 나옵니다.
    • 기본값: 0.8
  11. seed
    • 텍스트 생성에 사용할 난수 시드를 설정합니다. 특정 숫자를 설정하면 같은 프롬프트에서 항상 같은 결과를 생성합니다.
    • 기본값: 0
  12. stop
    • 특정 패턴을 만나면 텍스트 생성을 멈추게 할 정지 시퀀스를 설정합니다. 여러 개의 정지 패턴을 지정할 수 있습니다.
    • 기본값: "AI assistant:"
  13. tfs_z
    • 확률이 낮은 토큰의 영향을 줄이기 위해 사용되는 Tail Free 샘플링을 설정합니다. 값이 높을수록 낮은 확률의 토큰을 더 줄입니다.
    • 기본값: 1
  14. 💫num_predict
    • 텍스트 생성 시 예측할 최대 토큰 수를 설정합니다.
    • 기본값: 128 (-1 = 무한 생성, -2 = 문맥을 모두 채움)
  15. top_k
    • 무의미한 텍스트 생성을 줄이기 위한 설정입니다.
      • 값이 높을수록 더 다양한 응답을 생성하며, 값이 낮을수록 더 보수적인 응답을 생성합니다.
    • 기본값: 40
  16. top_p
    • top-k와 함께 작동하여, 값이 높을수록 더 다양한 텍스트를 생성하고, 값이 낮을수록 더 집중적이고 보수적인 텍스트를 생성합니다.
    • 기본값: 0.9

실험

parameter 값이 잘 적용되는지 확인하기 위해, 간단한 invoke 구문을 3개정도 돌려봤습니다.

import time
from langchain_community.llms.ollama import Ollama
from langchain.prompts import PromptTemplate

def test_llm_parameter(parameter):
    print("start")
    start_time = time.time()

    print(f"세팅 시작 및 파라미터 : {parameter}")
    llm = Ollama(model="llama2:latest", **parameter)
    prompt = PromptTemplate.from_template("What is {input}?")

    print("Chain running")
    chain = prompt | llm
    response = chain.invoke({"input": "AI"})

    end_time = time.time()
    duration = end_time - start_time
    print(f"execution time: {duration:.2f}s")

    return response

# 파라미터 리스트
params_list = [
    {
        "mirostat": 2,
        "temperature": 1.2,
        "num_predict": 50,
    },
    {
        "mirostat": 1,
        "temperature": 0.2,
        "num_predict": 100,
    },
    {"top_k": 10, "top_p": 0.5, "repeat_penalty": 1.8, "num_predict": 50},
]

for idx, params in enumerate(params_list):
    print("*" * 50, f"{idx+1}번째 시도", "*" * 50)
    print(test_llm_parameter(params))

모델에 상관없이 역시나 실행시간과 극적인 차이점을 보인 것은 토큰 수와 난해함의 정도 였습니다.

  • num_predict 를 50 / 100 으로 두고했을 때
  • 난해하거나 보수적인 정도를 낮췄을 때

이런 경우 속도가 훨씬 간결한 모습입니다.

ollama_parameters

Setting Bind

LLM 에 대한 세팅 값을 call 한 시점과 상관없이 세팅하거나, 여러개의 chain 을 둘때 유용한 메서드인 것 같습니다.

from langchain_community.llms.ollama import Ollama
from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "This system is professional on IT."),
        ("user", "{user_input}"),
    ]
)

model = Ollama(model="llama2:latest")

messages = prompt.format_messages(user_input="what is python language?")

before_answer = model.invoke(messages)

print("binding 이전 출력", before_answer)

chain = prompt | model.bind(num_predict=10)

after_answer = chain.invoke({"user_input": "what is python language?"})

print("binding 이후 출력", after_answer)

출력 결과는 다음과 같이 잘 적용된 모습을 볼 수 있습니다.

ollama_parameters
  • 토큰 수에 대한 정의는 모델에 따라 매우 상이하기 때문에, 토큰 수가 디테일하게 필요한 경우 get_token();pseudocode 같은 메서드는 필수로 작성 해야 합니다.
  • 모델별로 파라미터가 다르고, 사용&적용하는 방법 또한 매우 다릅니다.
  • 이는 곧, 하나의 모델에 익숙해져도 다른 모델을 사용하게 되는 경우 새로운 실험과 기록이 필요하다는 것을 의미합니다.
  • 잘 만들어진 여러 모델에 대한 특성들을 기록하는 것도 하나의 재미요소로 볼 수 있을 것 같습니다.
  • OPENAI 가 확실히 빠르고 좋긴하지만, 비용을 생각하면… Ollama 도 괜찮다고 생각합니다.

레퍼런스

ollama 깃허브

ollama parameters from modelfile

토큰수 discussions

hongreat 블로그의 글을 봐주셔서 감사합니다! 하단의 버튼을 누르시면 댓글을 달거나 보실 수 있습니다.

Buy Me A Coffee