Transformers documentation

도구 사용

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

도구 사용

Chat 모델은 일반적으로 “function-calling” 또는 “tool-use”를 지원하도록 학습됩니다. Tools는 사용자가 제공하는 함수이며, 모델은 응답의 일부로 이를 호출할 수 있습니다. 예를 들어, 모델은 내부적으로 계산을 수행하지 않고도 산술 연산을 수행하기 위해 계산기 tool에 접근할 수 있습니다.

이 가이드에서는 도구를 정의하는 방법, 채팅 모델에 도구를 전달하는 방법, 그리고 모델이 도구를 호출할 때 모델의 출력을 처리하는 방법을 보여줍니다.

도구 전달

모델이 tool-use를 지원하는 경우, apply_chat_template()의 tools 인자에 함수를 전달합니다. tools는 JSON schema 또는 Python 함수로 전달됩니다. Python 함수를 전달하면 인자, 인자 유형, 함수 docstring이 파싱되어 JSON schema가 자동으로 생성됩니다.

Python 함수를 전달하는 것은 매우 편리하지만, 파서는 Google 스타일 docstring만 처리할 수 있습니다. 도구 사용이 가능한 함수를 어떻게 포맷팅해야 하는지 확인하려면 아래 예시를 참조하세요.

def get_current_temperature(location: str, unit: str):
    """
    Get the current temperature at a location.

    Args:
        location: The location to get the temperature for, in the format "City, Country"
        unit: The unit to return the temperature in. (choices: ["celsius", "fahrenheit"])
    """
    return 22.  # A real function should probably actually get the temperature!

def get_current_wind_speed(location: str):
    """
    Get the current wind speed in km/h at a given location.

    Args:
        location: The location to get the wind speed for, in the format "City, Country"
    """
    return 6.  # A real function should probably actually get the wind speed!

tools = [get_current_temperature, get_current_wind_speed]

Returns: 블록을 docstring에, 반환 타입을 함수 헤더에 선택적으로 추가할 수 있지만 대부분의 모델은 이 정보를 사용하지 않습니다. 파서는 함수 내부의 실제 코드도 무시합니다!

실제로 중요한 것은 함수 이름, 인자 이름, 인자 유형, 그리고 함수의 목적과 인자의 목적을 설명하는 docstring입니다. 이들은 모델이 도구를 호출할지 여부를 결정하는 데 사용하는 “서명(signature)”을 만듭니다.

Tool-calling 예시

NousResearch/Hermes-2-Pro-Llama-3-8B와 같이 도구 사용(tool-use)을 지원하는 모델과 토크나이저를 로드하세요. 하드웨어가 지원할 경우 Command-R나 Mixtral-8x22B와 같은 더 큰 모델도 고려해 볼 수 있습니다.

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

checkpoint = "NousResearch/Hermes-2-Pro-Llama-3-8B"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForCausalLM.from_pretrained(checkpoint, dtype="auto", device_map="auto")

채팅 기록을 생성합니다.

messages = [
  {"role": "system", "content": "You are a bot that responds to weather queries. You should reply with the unit used in the queried location."},
  {"role": "user", "content": "Hey, what's the temperature in Paris right now?"}
]

다음으로 messages와 도구 목록을 apply_chat_template()에 전달합니다. 채팅을 토큰화하고 응답을 생성합니다.

inputs = tokenizer.apply_chat_template(messages, tools=tools, add_generation_prompt=True, return_dict=True, return_tensors="pt")
outputs = model.generate(**inputs.to(model.device), max_new_tokens=128)
print(tokenizer.decode(outputs[0][len(inputs["input_ids"][0]):]))
<tool_call>
{"arguments": {"location": "Paris, France", "unit": "celsius"}, "name": "get_current_temperature"}
</tool_call><|im_end|>

채팅 모델은 docstring의 올바른 매개변수를 사용하여 get_current_temperature 도구를 호출했습니다. 파리를 근거로 위치를 프랑스로 추론했으며, 온도 단위로 섭씨를 사용해야 한다고 판단했습니다.

모델은 도구를 직접 호출할 수 없습니다. 모델은 도구 호출을 요청할 뿐, 해당 호출을 처리하고 호출 및 결과를 채팅 히스토리에 추가하는 것은 사용자의 역할입니다. 응답 파싱을 지원하는 모델의 경우, 응답 파싱이 자동으로 처리되며 parse_response()를 사용하여 도구 호출을 추출할 수 있습니다. 다른 모델의 경우, 출력 문자열을 도구 호출 dict로 수동으로 변환해야 합니다.

어떤 방식을 사용하든, 도구 호출은 assistant 메시지의 tool_calls 키에 포함되어야 합니다. 이는 권장되는 API이며, 대부분의 도구 사용 모델의 채팅 템플릿에서 지원되어야 합니다.

tool_calls은 OpenAI API와 유사하지만, OpenAI API는 tool_calls 형식으로 JSON 문자열을 사용합니다. dict를 기대하는 Transformers에서 이를 사용하면 오류나 이상한 모델 동작이 발생할 수 있습니다.

tool_call = {"name": "get_current_temperature", "arguments": {"location": "Paris, France", "unit": "celsius"}}
messages.append({"role": "assistant", "tool_calls": [{"type": "function", "function": tool_call}]})

tool 역할을 사용하여 도구 응답을 채팅 히스토리에 추가합니다.

messages.append({"role": "tool", "content": "22"})  # Note that the returned content is always a string!

마지막으로, 모델이 도구 응답을 읽고 사용자에게 답변하도록 허용합니다.

inputs = tokenizer.apply_chat_template(messages, tools=tools, add_generation_prompt=True, return_dict=True, return_tensors="pt")
out = model.generate(**inputs.to(model.device), max_new_tokens=128)
print(tokenizer.decode(out[0][len(inputs["input_ids"][0]):]))
The temperature in Paris, France right now is 22°C.<|im_end|>

어시스턴트 메시지의 키 이름이 tool_calls이지만, 대부분의 경우 모델은 한 번에 하나의 tool call만 출력합니다. 일부 구형 모델은 동시에 여러 tool call을 출력하지만, 이는 여러 tool 응답을 한 번에 처리하고 tool call ID를 사용하여 이를 구분해야 하므로 훨씬 복잡한 과정입니다. 모델이 tool call에 대해 어떤 형식을 기대하는지 정확히 확인하려면 모델 카드를 참조하세요.

JSON 스키마

도구를 정의하는 또 다른 방법은 JSON schema를 전달하는 것입니다.

Python 함수를 JSON 스키마로 변환하는 저수준 함수를 수동으로 호출한 후, 생성된 스키마를 확인하거나 편집할 수도 있습니다. 이는 일반적으로 필요하지 않지만, 내부 작동 방식을 이해하는 데 유용합니다. 특히 도구 정의를 렌더링하기 위해 JSON 스키마에 접근해야 하는 채팅 템플릿 작성자에게 매우 중요합니다.

apply_chat_template() 메서드는 get_json_schema 함수를 사용하여 Python 콜러블을 JSON 스키마로 변환합니다. 여기에는 메서드가 포함되며, self와 cls는 암시적 수신자 인수로 간주되어 무시됩니다.

from transformers.utils import get_json_schema

def multiply(a: float, b: float):
    """
    A function that multiplies two numbers

    Args:
        a: The first number to multiply
        b: The second number to multiply
    """
    return a * b

schema = get_json_schema(multiply)
print(schema)
{
  "type": "function",
  "function": {
    "name": "multiply",
    "description": "A function that multiplies two numbers",
    "parameters": {
      "type": "object",
      "properties": {
        "a": {
          "type": "number",
          "description": "The first number to multiply"
        },
        "b": {
          "type": "number",
          "description": "The second number to multiply"
        }
      },
      "required": ["a", "b"]
    }
  }
}

JSON 스키마 자체에 대한 세부 사항은 이미 다른 곳에서 매우 잘 문서화되어 있으므로 여기서는 다루지 않습니다. 대신, Python 함수 대신 JSON 스키마 딕셔너리를 apply_chat_template()의 tools 인자로 전달할 수 있음을 언급합니다:

# A simple function that takes no arguments
current_time = {
  "type": "function",
  "function": {
    "name": "current_time",
    "description": "Get the current local time as a string.",
    "parameters": {
      'type': 'object',
      'properties': {}
    }
  }
}

# A more complete function that takes two numerical arguments
multiply = {
  'type': 'function',
  'function': {
    'name': 'multiply',
    'description': 'A function that multiplies two numbers',
    'parameters': {
      'type': 'object',
      'properties': {
        'a': {
          'type': 'number',
          'description': 'The first number to multiply'
        },
        'b': {
          'type': 'number', 'description': 'The second number to multiply'
        }
      },
      'required': ['a', 'b']
    }
  }
}

model_input = tokenizer.apply_chat_template(
    messages,
    tools = [current_time, multiply]
)
Update on GitHub