카테고리 보관물: 미분류

OpenAI API – GPT function calling 사용법

GPT function calling

OpenAI의 GPT API에서 얼마전부터 새롭게 제공하는 function calling 기능에 대한 설명입니다.

GPT function calling은 게임 체이저(Game changer)라고 블릴 만큼 굉장히 편하고 유용한 기능입니다. 이 기능을 이용하면 괜찮은 GPT 응용 애플리케이션을 매우 간단하게 만들 수 있습니다.

GPT function calling 설명

GPT function calling을 GPT에게 프롬프트와 함께 함수의 정의 목록을 함께 전달하면 GPT가 프롬프트를 보고 전달된 함수 중 하나를 호출해야 한다고 판단하면 그 중 하나를 호출해서 결과를 자신에게 전달해 달라고 하고 그 전달된 결과를 입력 받아 최종 메세지를 만드는 것을 말 합니다.

간단하게 플로우를 그려 보면 다음과 같습니다.

  1. GPT에게 프롬프트(질문)과 함께 함수 목록을 전달
  2. GPT가 프롬프트를 보고 함수를 실행 안해도 되면 그대로 메세지를 답변
  3. 만약 함수를 실행해서 그 결과가 필요하다면 함수를 실행해달라는 결과를 리턴
  4. GPT가 호출해달라고 한 함수를 사용자가 호출해서 결과값을 GPT에게 주고 다시 호출
  5. GPT가 이전의 프롬프트와 함수의 결과를 다 합쳐서 메세지를 만들어서 전달
  6. 만약 5에서 다시 다른 함수를 호출해야 한다면 3번으로 가게 됨

GPT function calling 예제 코드

아래 Python 코드를 살펴보시면 됩니다. 무척 쉽습니다.

중요한 점은 콘텍스트를 계속 유지해줘야 한다는 것입니다.

그래서 과거의 대화내역 뒤에 함수의 결과값을 다시 붙여줘야 제대로 대답합니다.

import openai
openai.api_key = "***** openai api key *****"

chat_completion: openai.ChatCompletion = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[
        {
            "role": "system",
            "content": "your name is Ironman. you anser in Korean",
        },
        {
            "role": "user",
            "content": """What is the weather like today?""",
        }
    ],
    functions=[
        {
            "name": "get_wether",
            "description": "get wether information",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "city or nation name",
                    }
                },
                "required": ["location"],
            },
        }],
    function_call="auto",
)

if chat_completion.choices[0].finish_reason == "function_call":
    function_name = chat_completion.choices[0].message.function_call.name
    functoin_arguments = chat_completion.choices[0].message.function_call.arguments
    # 함수 실행 부분을 추가
    # function_result에는 함수를 실행하고 난 결과값을 넣어준다.
    function_result = "function result"

    messages = [
        {
            "role": "system",
            "content": "your name is Ironman. you anser in Korean",
        },
        {
            "role": "user",
            "content": """What is the weather like today?""",
        },
        {
            "role": "function",
            "name": function_name,
            "content": function_result
        }
    ]
    
    second_chat_completion: openai.ChatCompletion = openai.ChatCompletion.create(
        model="gpt-4",
        messages=messages,
    )
    result_message = second_chat_completion.choices[0].message.content
else:
    result_message = chat_completion.choices[0].message.content

print(result_message)

BigQuery로 KNN 최근접 이웃 계산하기

BigQuery로 Consine similarity를 계산해서 KNN 최근접 이웃을 계산하는 예제 코드입니다.

KNN = K Nearest Neighbor = 최근접 이웃
최근접 이웃은 기계학습에서 매우 오래된 기법입니다. 간단하지만 매우 정확한 시스템이지만 데이터프로세싱에 많은 자원이 소모되기 때문에 잘 사용되지는 않습니다.

Cosine Distance함수는 BigQuery에서 빠른 것을 제공을 해주기 때문에 따로 만들지 않고 제공하는 것을 그냥 쓰면 됩니다.

하지만 결국 BigQuery를 쓴다 해도 cross join을 해야합니다.

아무리 빅쿼리라고 해도 처리하는 데이터가 조금만 커도 cross join은 잘 실행되지 않습니다.
그래서 빅쿼리로 하는 KNN은 실용성이 있다고 보기는 어렵습니다.

작은 데이터에 대해서만 가능하기 때문에 그 점을 참고하시기 바랍니다.

WITH tbl_left AS (SELECT group_id, word AS word1, vector AS vector1
              FROM recsys.recsys_word2vec
              WHERE _PARTITIONTIME IS NOT NULL
              AND group_id = '12345'
              )
   , tbl_right AS (SELECT group_id, word AS word2, vector AS vector2
              FROM recsys.recsys_word2vec
              WHERE _PARTITIONTIME IS NOT NULL
              AND group_id = '12345'
              )
select a.group_id, a.word1
, ARRAY_AGG(b.word2 ORDER BY ML.DISTANCE(a.vector1, b.vector2, 'COSINE') DESC LIMIT 50) as nn50
FROM tbl_left a
               JOIN tbl_right b
                    ON a.group_id = b.group_id AND a.word1 != b.word2
GROUP BY a.group_id, a.word1
;

유용한 리눅스 커맨드 Linux Command List


리눅스 커맨드는 잘 배우면 간단한 작업을 즉시 하기에 매우 편리하고 좋지만

제대로 신경쓰지 않으면 좀처럼 익히기 쉽지 않습니다.

적응하기 어렵습니다. 그래서 시간 날 때 연습하고 연마해야 합니다.

배울 때는 고생스럽지만 배우고 나면 생산에 매우 큰 도움이 되는 도구가 됩니다.

능력있는 개발자, 엔지니어가 되려면 필수 명령어는 반드시 외워서 사용해야 합니다.

잘 정리된 문서가 있어 여기 링크를 올려 둡니다.

https://github.com/jlevy/the-art-of-command-line/blob/master/README-ko.md

Database CTE (Common Table Expression)

SQL에는 쿼리를 실행할 때 그 순간만 사용할 테이블을 잠깐 만들어서 사용할 수 있습니다.

이때 JOIN절에서 임시 테이블을 만드는 방법과 select하기 전에 with절로 임시 테이블을 만드는 방법이 있습니다.

쿼리 내에서 임시 테이블을 만드는 방법 2가지

  • 인라인뷰(Inline view): Join 구문에서 select를 사용해서 쿼리를 실행하고 이름을 붙여 테이블 처럼 사용
  • CTE (Common Table Expression): select하기 전에 with절로 select 구문을 묶어서 이름을 붙이고 공통 테이블처럼 사용

CTE의 장점은 한 번 작성하고 뒤에서 이름을 이용해서 여러번 참조할 수 있다는 장점이 있습니다.

다시 정리하면

CTE (Common Table Expression)

CTE (Common Table Expression)는 SQL 쿼리에서 일시적으로 사용되는 결과 세트를 정의하는 방법입니다. CTE는 복잡한 쿼리를 간단하게 만들고, 코드를 재사용하며, 가독성을 높여주는 도구입니다. CTE는 ‘WITH’ 절을 사용하여 정의되며, 이어지는 SELECT, INSERT, UPDATE, DELETE 문에서 참조할 수 있습니다.

MariaDB에서 CTE를 사용한 예제:

단순한 CTE 예제 (사용자 정보 가져오기):

WITH user_cte AS (   SELECT id, name, age   FROM users ) SELECT * FROM user_cte;

이 예제에서는 user_cte라는 CTE를 생성하고, users 테이블에서 id, name, age를 가져옵니다. 그 다음, user_cte를 참조하여 결과를 가져옵니다.

재귀 CTE 예제 (계층적 카테고리 정보 가져오기):

WITH RECURSIVE category_cte (id, parent_id, name, depth) AS (   SELECT id, parent_id, name, 0   FROM categories   WHERE parent_id IS NULL   UNION ALL   SELECT c.id, c.parent_id, c.name, p.depth + 1   FROM categories c   JOIN category_cte p ON c.parent_id = p.id ) SELECT * FROM category_cte ORDER BY depth, id;

이 예제에서는 category_cte라는 재귀 CTE를 사용하여, 계층적 카테고리 정보를 가져옵니다. 초기에는 상위 카테고리(즉, parent_id가 NULL인) 정보를 가져온 후, UNION ALL을 사용하여 하위 카테고리 정보를 가져옵니다. 그 다음, category_cte를 참조하여 결과를 가져옵니다.

다중 CTE 예제 (사용자 정보와 주문 정보 동시에 가져오기):


WITH user_cte AS (<br>  SELECT id, name, age<br>  FROM users<br>),<br>orders_cte AS (<br>  SELECT id, user_id, total<br>  FROM orders<br>)<br>SELECT u.name, u.age, o.total<br>FROM user_cte u<br>JOIN orders_cte o ON u.id = o.user_id;<

 

이 예제에서는 두 개의 CTE를 생성합니다. user_cte에서는 사용자 정보를 가져오고, orders_cte에서는 주문 정보를 가져옵니다. 그 다음, 두 CTE를 조인하여 결과를 가져옵니다.

Chatbot개발을 위한 KoAlpaca

Alpaca는 Facebook에서 공개한 LLama 모델을 스탠포드에서 개량한 것입니다.

Alpaca에 한국어 학습데이터를 추가한 것이 KoAlpaca입니다.

GPT API가 과금 문제가 있고 제차 빌드를 하려면 비용이 많이 들기 때문에 KoAlpaca의 공개된 엔진을 사용해서 어설픈 챗봇을 만들기로 했었습니다.

하지만 아래와 같은 이유로 포기했습니다.

포기 이유

  • GPU 없이 모델을 로딩해서 인퍼런스(문장완성이나 답변)을 뽑는 것이 너무 느림
  • GPU를 사용하려면 3080ti 같은 PC급 GPU로는 가장 가벼운 모델도 로딩하기 어려움
  • 원할한 서빙을 위해서 A100 이상의 GPU로 서빙을 해야 하는데 비용이 높음
  • KoAlpaca의 품질이 GPT 3.5에 비해서도 확인히 떨어짐. 한국어는 매우 심함

현실적으로 챗봇의 품질을 확보하려면 GPT API를 사용하거나 Azure를 사용하는 것이 가장 품질과 비용을 고려한 솔루션이 될 것 같습니다.

KoAlpaca는 누군가 모델을 더 개선할 때까지 기다려야 할지 모르겠네요.