Tech

랭체인을 사용하여 나만의 LLM 구축하기(1)

민윤홍 2024. 10. 28. 17:33
반응형

안녕하세요 민윤홍입니다.

 

정말.. 정말 오랜만에 블로그 포스트를 하게 되었습니다!

사실 블로그 포스트에 손을 뗀지는 조금 오래 되긴 하였지만, 이번에 카카오임팩트에서 진행하는 누구나데이터 LAB을 참가하게 되었고, 좋은 기회로 포스팅도 같이 하게되어 다시 열심히 작성해보고자 합니다!
여기까지는 주저리주저리였고, 아래 내용을 확인하시면 됩니다.
 

sqlcoder-8b 적용하기

sqlcoder-8b 모델은 Llama3 기반으로 설계되었으며, 텍스트 입력을 SQL 쿼리로 변환하는 Text-to-SQL 작업에 특화된 강점을 가지고 있습니다. 이 모델을잘 활용한다면 궁극적인 목적인 자연어로 데이터베이스에 질의할 수 있어, 데이터 접근성을 크게 높일 수 있습니다. 

https://huggingface.co/defog/llama-3-sqlcoder-8b/tree/main

 

defog/llama-3-sqlcoder-8b at main

This model has 1 file scanned as suspicious. Show files

huggingface.co

 

GPU 할당량

sqlcoder-8b

대략 31000MiB 정도 할당된다.

아래는 sqlcoder-8b 모델을 적용한 코드 예시입니다.

from langchain import LLMChain
from langchain.prompts import PromptTemplate
from langchain.llms import HuggingFacePipeline
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline

# 모델 경로와 토크나이저 로드
# model_path는 본인이 다운로드받은 모델의 경로를 입력.
model_path = #본인이 다운받은 모델 경로
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(model_path)

# 파이프라인 객체 생성
pipe = pipeline(
    "text-generation",
    model=model,
    tokenizer=tokenizer,
    device=1,  # 1번 GPU 사용(A100 80GB)
    model_kwargs={"temperature": 0.0, "max_length": 200}
)

# HuggingFacePipeline 객체 생성
llm = HuggingFacePipeline(pipeline=pipe)

# 프롬프트 템플릿 정의
template = """질문: {question}
답변: """
prompt = PromptTemplate.from_template(template)

# LLM Chain 객체 생성
llm_chain = LLMChain(prompt=prompt, llm=llm)

위와 같은 형태로 LLM 체인을 구성하면 됩니다.

 

이후 사용 예시로 아래와 같이 임의의 DB를 만들어 이 테이블의 정보를 Insturction 으로 주고 질문을 주어 답변을 실행해보았다.

    You are an expert database administrator.
    Given a natural language question and the table schema, generate an SQL query that answers the question.

	##출력을 위한 예시 테이블
    Table Schema:
    campaign_board (
        campaign_id INTEGER PRIMARY KEY AUTOINCREMENT,        -- 캠페인 고유 ID
        title TEXT NOT NULL,                                  -- 캠페인 제목
        description TEXT,                                     -- 캠페인 설명
        created_by TEXT NOT NULL,                             -- 작성자 (캠페인 등록자)
        start_date DATE,                                      -- 캠페인 시작일
        end_date DATE,                                        -- 캠페인 종료일
        total_funds REAL DEFAULT 0,                           -- 모금된 총 금액
        view_count INTEGER DEFAULT 0,                         -- 게시글 조회수
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,       -- 게시글 생성일
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP        -- 게시글 수정일
    );

    Generate an appropriate SQL query based on the question.

    Question: """ + question + """

    SQL Query:

결과

Question: 신규 사용자에 의한 특정 이벤트가 발생한 페이지 정보

Query
SELECT 
	l.landing_page, l.page_title, l.source_medium, l.source, l.medium, l.campaign, l.content, l.term, 
	l.source_platform, l.session, l.host_name, l.user, l.new_user, l.returning_user, l.regular_purchase, 
	l.regular_user_id, l.once_purchase, l.once_user_id, l.regular_value, l.once_value 
FROM 
	landing_report l 
JOIN 
	events e ON l.user = e.user_id 
WHERE 
	e.event_name = 'purchase' AND l.new_user = 'yes';
	
결과
('/home', 'Product Page', 'facebook/organic', 'facebook', 'organic', 'lead_gen', 'welcome', 'discount', 'mobile', 'session_92', 'example.com', 'user_17', 'yes', 'no', 'yes', 'regular_40', 'no', None, 8, 0)
('/checkout', 'Checkout Page', 'twitter/organic', 'twitter', 'organic', 'fall_campaign', 'new_post', 'holiday', 'desktop', 'session_7', 'example.com', 'user_43', 'yes', 'no', 'no', None, 'yes', 'once_30', 0, 34)
('/home', 'Home Page', 'google/cpc', 'google', 'cpc', 'winter_sale', 'offer', 'discount', 'desktop', 'session_2', 'shoponline.com', 'user_61', 'yes', 'no', 'no', None, 'no', None, 0, 0)
('/blog', 'Checkout Page', 'google/cpc', 'google', 'cpc', 'lead_gen', 'promo', 'blog', 'web', 'session_97', 'shoponline.com', 'user_14', 'yes', 'no', 'no', None, 'no', None, 0, 0)
...
('/blog', 'Pricing Page', 'google/cpc', 'google', 'cpc', 'blog_launch', 'welcome', 'blog', 'web', 'session_67', 'shoponline.com', 'user_61', 'yes', 'no', 'yes', 'regular_5', 'no', None, 11, 0)
('/pricing', 'Checkout Page', 'google/cpc', 'google', 'cpc', 'lead_gen', 'offer', 'holiday', 'web', 'session_95', 'example.com', 'user_64', 'yes', 'no', 'yes', 'regular_82', 'no', None, 57, 0)
('/pricing', 'Product Page', 'twitter/organic', 'twitter', 'organic', 'fall_campaign', 'join', 'holiday', 'mobile', 'session_33', 'testsite.com', 'user_46', 'yes', 'no', 'yes', 'regular_20', 'no', None, 73, 0)
('/pricing', 'Product Page', 'facebook/organic', 'facebook', 'organic', 'fall_campaign', 'promo', 'b2b', 'mobile', 'session_89', 'shoponline.com', 'user_45', 'yes', 'no', 'no', None, 'yes', 'once_84', 0, 80)

위와 같이 제법 쿼리문을 잘 만들어준다. 두개의 테이블의 연산이 필요한 경우도 Join문을 만들어 해결하는 모습이다.

생각보다 성능이 괜찮은거 같으니, 테스트 평가세트를 만들어 LLM성능 테스트를 해보는 것도 좋아보인다.

 

너무 두서없이 작성했지만, 일기장처럼 포스팅할 예정이니 넓은 아량 부탁드립니다 하핳...