NLP

[Langchain] LLM/BitsandBytes 기반 Quantization LLM + Langchain 함께 사용하기

메린지 2024. 4. 24. 23:36

요새 랭체인을 공부중이다. << 논문써야함 ㅠ

 

근데 저에겐 3090 only one,, 당연히 그래서 원랜 서버 대여할랬는데 생각해보니

모델이 하도 크니까 quantization 모델들이 많이 나오지 않을까 싶어 찾아봤더니 역시나

bitsandbytes도 물론이지만 여러모로 방법이 있는듯했다 << gguf,,? safetensors,,? 공부할게 넘 많다 ㅠ

 

각설하고 우선 제가 지나친 과정을 설명해보도록 하겠습니당 !!

 

1. Dependency 부터 설치

!pip install -q -U bitsandbytes
!pip install -q -U git+https://github.com/huggingface/transformers.git
!pip install -q -U git+https://github.com/huggingface/peft.git
!pip install -q -U git+https://github.com/huggingface/accelerate.git
!pip install -q -U safetensors
!pip install -q -U torch
!pip install langchain
!pip install langchain_community

 

사실 이 git 패키지들은 업데이트가 되기 때문에 안되면 버전 업그레이드 하거나 다운그레이드 해줘야할 수 있슴당.

 

그리고!! 중요한것,

저는 윈도우10이기 때문에 bitsandbytes 를 윈도우 버전으로 설치해줘야 합니다.

+

pip uninstall bitsandbytes # 만약 이미 설치했다면
pip install https://github.com/jllllll/bitsandbytes-windows-webui/releases/download/wheels/bitsandbytes-0.41.0-py3-none-win_amd64.whl

 

2. 4-bit 양자화(Quantization)을 위한 BitsandBytes config 설정

import torch
from transformers import BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(
    load_in_4bit=True, # 4bit 할 것이냐
    bnb_4bit_compute_dtype=torch.float16, #bfloat16 or float16
    bnb_4bit_quant_type="nf4", # nf4 or fp4
    bnb_4bit_use_double_quant=True, # nf4 + fp4 이중 양자화 사용여부(성능은 크게 안다르고, 양자화 정확도 때문인듯)
)

 

양자화 모델을 쓸것이라면 설정해주세용

 

3. 모델 로드 <허깅페이스 기반>

3-1) 양자화 없는 모델의 경우

여기서는 api-key로 허용해줘야 합니다.

그래서 key 받아와서 허용해주고,

repo_id + task 설정해줍니다.

==> 이 친구들은 뒤에 HuggingFaceHub 써야해서 그렇슴니당

## api-key
os.environ['HUGGINGFACEHUB_API_TOKEN'] = '개인 api-key'
repo_id = "beomi/open-llama-2-ko-7b"
task='text-generation'

llm = HuggingFaceHub(
     repo_id=repo_id,
     task=task,
     model_kwargs={
         "temperature": 0.75,
         "max_tokens": 512,
         "verbose": True,
     }
 )

 

 

3-2) 양자화 모델의 경우

먼저, 원래 quant 모델 불러오는 거처럼 config 넘겨주면서 불러옵니다.

model_name = "beomi/open-llama-2-ko-7b"
device_map = {"": 0} # device check

## 모델 불러오기
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    device_map=device_map,
    quantization_config=bnb_config
)
model.config.use_cache = True # inference

## 토크나이저 불러오기
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
tokenizer.pad_token = tokenizer.eos_token

 

4. pipeline 구축

 

이 부분은 양자화했을 때만 적용하면 됩니다.

pipe = pipeline(
        task=task,
        model=model,
        tokenizer=tokenizer,
        use_cache=True,
        device_map=device_map,
        max_length=512,
        do_sample=True,
        top_k=7,
        num_return_sequences=1,
        eos_token_id=tokenizer.eos_token_id,
        pad_token_id=tokenizer.eos_token_id,
)
llm = HuggingFacePipeline(pipeline=pipe)

 

5. Model과 LangChain 연결하기

text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=500,
        chunk_overlap=0
    )

loader = CSVLoader(file_path=file_path, encoding='utf-8')
train_data = loader.load()

all_splits = text_splitter.split_documents(train_data)

posts = Chroma.from_documents(
        documents=all_splits,
        embedding=embeddings
)

prompt = PromptTemplate(
        template="""너는 다음 질문에 대한 답을 본문을 기반으로 해야 해.\n질문: {question}
        {context}
        답: """,
        input_variables=["question", "context"]
)
    
qa_chain = RetrievalQA.from_chain_type(
        llm=llm,
        retriever=posts.as_retriever(),
        chain_type_kwargs={"prompt": prompt}
)

question = 'OTP는 무슨 글자의 약자야?'
result = qa_chain({'query': question, 'context': qa_chain.retriever})

 

1) 데이터 로드 => 각자 데이터 로드하고, text_splitter로 chunking함

2) Chorma.from_documents 로 DB구축

3) prompt는 랭체인 hub 라이브러리에서 rag-prompt가 따로 있던데, 그거불러와도 되고 난 새로 템플릿을 짰당

4) qa_chain 이라고 Retrieval될 Chain을 구상해줌

5) 그리고 질문하면 작동!!!!

 

근데 챗봇 형태로 학습안한거라 좀 답변 별로긴함니다.,.

{'query': 'OTP는 무슨 글자의 약자야?', 'context': VectorStoreRetriever(tags=['Chroma', 'HuggingFaceEmbeddings'], vectorstore=<langchain_community.vectorstores.chroma.Chroma object at 0x0000022AD446B8E0>), 'result': '너는 다음 질문에 대한 답을 본문을 기반으로 해야 해.\n질문: OTP는 무슨 글자의 약자야?\n 상기 인증된 사용자의 OTP 매체로 제공하기 위해 서버 측에서 동적으로 생성된 N(N≥2)자리수의 OTP를 확인하고, 상기 인증된 사용자의 OTP 매체에 대응하는 사용자 휴대폰의 특정 프로그램으로 상기 N자릿수의 OTP를 제공하는 절차를 수행하며, 상기 별도의 매체 식별자는, 상기 휴대폰의 기 설정된 시스템 영역에 저장된 전화번호와 일련번호가 아닌 별도의 중복되지 않는 코드값인 네트워크 형 오티피 제공 방법에 관한 것이다.\n\n0: 본 발명은 서버에 의해 실행되는 방법에 있어서, 특정 프로그램을 구비한 사용자 휴대폰을 지정된 인증 절차의 OTP(One Time Password)를 구현하는 사용자의 OTP 매체임을 인증하기 위해 중복되지 않는 코드값 형태로 상기 사용자 휴대폰의 지정된 저장영역에 저장된 별도의 매체 식별자를 포함하는 매체 정보를 확인하여 지정된 저장매체에 저장시키는 절차를 수행하고, 상기 사용자 휴대폰에서 상기 특정 프로그램을 구동 시, 상기 사용자 휴대폰에서 구동된 특정 프로그램과 통신하여 상기 특정 프로그램을 통해 상기 사용자 휴대폰의 지정된 저장영역으로부터 추출된 별도의 매체 식별자를 포함하는 매체인증 정보를 수신하고 상기 저장된 매체 정보를 통해 상기 매체인증 정보에 포함된 상기 별도의 매체 식별자를 비교 인증하여 상기 특정 프로그램을 구동한 사용자 휴대폰을 사용자의 OTP 매체로 인증하는 절차를 수행하고, 상기 특정 프로그램을 구동한 사용자 휴대폰을 사용자의 OTP 매체로 인증 시,\n\n0: 네트워크 형 오티피 제공 방법(Method for Providing Network type OTP)\n\n0: 그리고, 본 발명의 일 실시예에 따른 영상 복원 시스템은 500MHz에서 3GHz까지 UHF 대역 전자파뿐만 아니라, 다른 주파수 대역을 갖는 전자파를 이용할 수 있다.\n 답: 400MHz, 500MHz, 514MHz, 57MHz 등\n\n0: 그리고, 본 발명의 일 실시예에 따른 영상 복원 시스템은 500MHz에서 3GHz까지 UHF 대역 전자파뿐만 아니라, 다른 주파수 대역을 갖는 전자파를 이용할 수 있다.\n 답: 400MHz, 500MHz, 514MHz, 57MHz 등\n\n0: 또한, 본 발명의 일 실시예에 따른 영상 복원 시스템은, 1GHz에서 10GHz까지의 고주파 대역 전자파뿐만 아니라, 다른 주파수 대역의 전자파를 이용할 수도 있다.\n 답: 1GHz에서 10GHz까지의 고주파 대역 전자파뿐만 아니라, 다른 주파수 대역의 전자파를 이용할 수도 있다.\n그리고, 본 발명의 일 실시예에 따른 영상 복원 시스템은, 1GHz에서 10GHz까지의 고주파 대역 전자파뿐만 아니라, 다양한 대역 및 파장(Wavelength)을 갖는 전자파를 사용할 수도 있다.\n 답: 1GHz에서 10GHz까지의 고주파 대역 전자파뿐만 아니라, 다양한 대역 및 파장(Wavelength)을 갖는 전자파를 사용할 수도 있다.\n그리고, 본 발명의 일 실시예에 따른 전자파를 이용한 영상 복원 방법은, 500MHz에서 3GHz까지 UHF 대역의 전자파 뿐만 아니라, 다른 주파수 대역을 갖는 전자파를 이용할 수도 있다.\n 답: 500MHz에서 3GHz까지 UHF 대역의 전자파 뿐만 아니라, 다른 주파수 대역을 갖는 전자파를 이용할 수도 있다.\n그리고, 본 발명의 일 실시예에 따른 전자파를 이용한 영상 복원 방법은, 1GHz에서 10GHz까지의 고주파 대역 전자파뿐만 아니라, 다른 주파수 대역의 전자파를 이용할 수도 있다.\n 답: 1GHz에서 10GHz까지의 고주파 대역 전자파뿐만 아니라, 다른 주파수 대역의 전자파를 이용할 수도 있다.\n또한, 본 발명의 일 실시예에 따른 전자파를 이용한 영상 복원 방법은, 1GHz에서 10GHz까지의 고주파 대역 전자파뿐만 아니라, 다양한 대역 및 파장(Wavelength)을 갖는 전자파를 사용할 수도 있다.\n 답: 1GHz에서 1'}