머신러닝AI2024. 3. 1. 09:32

 

개인비서 서비스가 LLM덕분에 가시권에 들어왔다. Siri도 그렇고 많은 사실은 많은 회사들이 이 개인비서를 꿈꿔왔다. 바쁜 현대인들은 대신 해줬으면 하는게 많기 때문이다. 인공지능이라는 이름으로 그동안 많은 서비스들이 이를 지향했는데, 사실 잘 안되었다. if-then 으로는 처리에 한계가 있었기 때문이다. 곧 사람들이 외면하기가 일쑤였다.

ChatGPT 생성


 그런데 LLM은 이미 OpenAI를 통해 어느정도의 사용자 경험을 인식시키고 있다. 청소년 정도의 응대만 가능해도 맡기고 싶은 일이 얼마나 많은가.

 

 하루를 한번 돌이켜보자. 몇시에 일어나서 밤사이 특별한 일은 없었는지(특히 해외 등), 날씨는 어떻고 우산을 가져갈지 말아야할지, 출근길에 특이한 정체나 사건은 없는지, 출근해서는 업무를 수행하기 위한 수많은 것들도 그렇고(임원들의 비서가 처리하는 수많은 것), 식당을 알아보고 일정을 조절하고는 기본이다.

 

 내 생활에서는 자녀를 위한 여러가지 교육 정보도 아쉽다. 내가 사는 지역에 특이한 일은 없는지, 내가 관심있는 주제는 어떤 변화가 있는지, 내 자산에는 알아야할 특이 정보는 없을지, 고민에 대한 상담, 여러가지 장기적인 관점의 진단은 특정 품질 이상으로 이런 것을 모두 챙겨줄 수 있다면 몇만원의 돈이 무엇이 아깝겠는가. 따라서 이 분야의 대형 서비스가 나올 수 있다고 생각한다.

 

 GPTs가 이런 비서 시장을 노릴테지만 여러가지 각각의 주제별로 조금더 전문화하고 다듬는 일이 필요하다. 그러다보면 각 전문분야별로 실제 정보나 컨텐츠가 부족하게 된다. 이러다보면 세상의 검색이나 여러가지 서비스가 API형태로 LLM이 쓸 수 있도록 변형되는 일이 가속화될것이다. 그렇게 더 발전하면 사람들이 직접 그 웹사이트에 들어가는 것보다는 API화 되어 LLM이 쓰는 양이 더 많아지고, 이제 사람들이 직접 사이트에 들어가는 것은 구식으로 느껴질 날이 올지도 모르겠다.

 

 이런 기술 환경의 핵심에는 Langchain같은 LLM을 다양하게 agent형으로 활용하는 오픈소스와 기존의 각종 서비스를 크롤링하고 API화되어가는 세상이 오는것. 비서 역할을 할 수 있는 사람이 있는 회사 임원들은 업무 사이트에 잘 들어가지 않는다. 사이트를 배우는 일도 큰 부담이기 때문이다. 이런 일을 LLM이 대신 해주는 세상이 곧 펼쳐지겠다.

 

 이런 변화가 오고있다. 영화 Her의 비서가 곧 세상을 점령해나갈 태세다.

반응형
Posted by 작동미학
머신러닝AI2024. 2. 23. 01:32

Gemma 공개후 곧바로 파인튜닝 가능한 가이드가 공개되었다.

https://adithyask.medium.com/a-beginners-guide-to-fine-tuning-gemma-0444d46d821c

 

A Beginner’s Guide to Fine-Tuning Gemma

A Comprehensive Guide to Fine-Tuning Gemma

adithyask.medium.com

 

gemma-2b-it 모델의 quantized 버전 정도는 16GB GPU로도 파인튜닝 테스트를 해볼 수 있다.

 

상기 가이드대로 GPU환경에서 python을 설치한다.

$ conda create -n gemma python=3.11

$ conda activate gemma

$ pip install bitsandbytes==0.42.0
$ pip install peft==0.8.2
$ pip install trl==0.7.10
$ pip install accelerate==0.27.1
$ pip install datasets==2.17.0
$ pip install transformers==4.38.0

 

아래 소스를 통해 샘플 데이터 셋을 허깅페이스에서 다운받아 파인튜닝해서 결과를 얻어볼 수 있다.

이때 허깅 페이스에 미리 계정을 만든 후 WRITE 가능한 token으로 로그인을 미리 해두자. WRITE 권한으로 생성한 토큰으로는 모델을 huggingface에 업로드 하는 것도 가능하다(아래 소스의 맨 마지막 두줄)

 

$ huggingface-cli login
...
Token: 

$ huggingface-cli whoami
Justik (필자의 profile이다)

 

아래 코드를 실행한다. LORA를 통한 경량형 튜닝 정도는 할 수 있게 된다. gemma-7b-it의 경우는 16gb에서는 메모리가 부족하다. (본래 글에서는 A100을 추천하고 있다.) gemma-2b-it의 경우는 아래의 코드로 10~14gb정도의 메모리를 소모한다.

import json
import pandas as pd
import torch
from datasets import Dataset, load_dataset
from huggingface_hub import notebook_login
from peft import LoraConfig, PeftModel
from peft import LoraConfig, get_peft_model
lora_config = LoraConfig(
    r=64,
    lora_alpha=32,
    target_modules=['o_proj', 'q_proj', 'up_proj', 'v_proj', 'k_proj', 'down_proj', 'gate_proj'],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
) 
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
    TrainingArguments,
    pipeline,
    logging,
)
from trl import SFTTrainer

notebook_login()

#model_id = "google/gemma-7b-it"
# model_id = "google/gemma-7b"
model_id = "google/gemma-2b-it"
#model_id = "google/gemma-2b"

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_use_double_quant=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16
)

#model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=lora_config, device_map={"":0})
model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=bnb_config, device_map={"":0})
#model = AutoModelForCausalLM.from_pretrained(model_id, device_map={"":0})
tokenizer = AutoTokenizer.from_pretrained(model_id, add_eos_token=True)
{
    "instruction": "Create a function to calculate the sum of a sequence of integers.",
    "input":"[1, 2, 3, 4, 5]",
    "output": "# Python code def sum_sequence(sequence): sum = 0 for num in sequence: sum += num return sum"
}

dataset = load_dataset("TokenBender/code_instructions_122k_alpaca_style", split="train")

def generate_prompt(data_point):
    """Gen. input text based on a prompt, task instruction, (context info.), and answer

    :param data_point: dict: Data point
    :return: dict: tokenzed prompt
    """
    prefix_text = 'Below is an instruction that describes a task. Write a response that appropriately completes the request.\\n\\n'
    # Samples with additional context into.
    if data_point['input']:
        text = f"""<start_of_turn>user {prefix_text} {data_point["instruction"]} here are the inputs {data_point["input"]} <end_of_turn>\\n<start_of_turn>model{data_point["output"]} <end_of_turn>"""
    # Without
    else:
        text = f"""<start_of_turn>user {prefix_text} {data_point["instruction"]} <end_of_turn>\\n<start_of_turn>model{data_point["output"]} <end_of_turn>"""
    return text

# add the "prompt" column in the dataset
text_column = [generate_prompt(data_point) for data_point in dataset]
dataset = dataset.add_column("prompt", text_column)
dataset = dataset.shuffle(seed=1234)  # Shuffle dataset here
dataset = dataset.map(lambda samples: tokenizer(samples["prompt"]), batched=True)

dataset = dataset.train_test_split(test_size=0.2)
train_data = dataset["train"]
test_data = dataset["test"]

model = get_peft_model(model, lora_config)
trainable, total = model.get_nb_trainable_parameters()
print(f"Trainable: {trainable} | total: {total} | Percentage: {trainable/total*100:.4f}%")

import transformers

from trl import SFTTrainer

tokenizer.pad_token = tokenizer.eos_token
torch.cuda.empty_cache()
trainer = SFTTrainer(
    model=model,
    train_dataset=train_data,
    eval_dataset=test_data,
    dataset_text_field="prompt",
    peft_config=lora_config,
    args=transformers.TrainingArguments(
        per_device_train_batch_size=1,
        gradient_accumulation_steps=4,
        warmup_steps=0.03,
        max_steps=100,
        learning_rate=2e-4,
        logging_steps=1,
        output_dir="outputs",
        optim="paged_adamw_8bit",
        save_strategy="epoch",
    ),
    data_collator=transformers.DataCollatorForLanguageModeling(tokenizer, mlm=False),
)

# Start the training process
trainer.train()

new_model = "gemma-2b-it-finetune" #Name of the model you will be pushing to huggingface model hub
# Save the fine-tuned model
trainer.model.save_pretrained(new_model)

# Merge the model with LoRA weights
base_model = AutoModelForCausalLM.from_pretrained(
    model_id,
    low_cpu_mem_usage=True,
    return_dict=True,
    torch_dtype=torch.float16,
    device_map={"": 0},
)
merged_model= PeftModel.from_pretrained(base_model, new_model)
merged_model= merged_model.merge_and_unload()

# Save the merged model
merged_model.save_pretrained("merged_model",safe_serialization=True)
tokenizer.save_pretrained("merged_model")
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"


def get_completion(query: str, model, tokenizer) -> str:
  device = "cuda:0"
  prompt_template = """
  <start_of_turn>user
  Below is an instruction that describes a task. Write a response that appropriately completes the request.
  {query}
  <end_of_turn>\\n<start_of_turn>model
  
  """
  prompt = prompt_template.format(query=query)
  encodeds = tokenizer(prompt, return_tensors="pt", add_special_tokens=True)
  model_inputs = encodeds.to(device)
  generated_ids = model.generate(**model_inputs, max_new_tokens=1000, do_sample=True, pad_token_id=tokenizer.eos_token_id)
  # decoded = tokenizer.batch_decode(generated_ids)
  decoded = tokenizer.decode(generated_ids[0], skip_special_tokens=True)
  return (decoded)

result = get_completion(query="code the fibonacci series in python using reccursion", model=merged_model, tokenizer=tokenizer)
print(result)


# Push the model and tokenizer to the Hugging Face Model Hub
# merged_model.push_to_hub(new_model, use_temp_dir=False)
# tokenizer.push_to_hub(new_model, use_temp_dir=False)

 

이렇게 hugging face hub에 올려진 모델은 아래와 같다.

https://huggingface.co/Justik/gemma-2b-it-finetune

 

Justik/gemma-2b-it-finetune · Hugging Face

Model Card for Model ID Finetune model of Google Gemma 2b it Model Details Model Description This is the model card of a 🤗 transformers model that has been pushed on the Hub. This model card has been automatically generated. Developed by: Justin Kim Fin

huggingface.co

 

반응형
Posted by 작동미학
자연철학2024. 2. 12. 09:36

역대의 물리학 혁명을 거론할때 빼놓을 수 없는 주제가 바로 중력이다.

 

 가장 위대한 물리학자를 꼽으라는 투표에서 흔히 등장하는 것이 뉴튼, 맥스웰, 아인슈타인인데, 뉴튼과 아인슈타인이 같이 연결된 것이 바로 중력이다. 물리학이 천문학에서 유래했다면, 별들을 예측하는데 가장 중요한 발견이 중력에 대한 것이다. 그러나 이 중력을 둘러싼 해석은 역사적으로 다양했고, 아인슈타인이 등장한 이후에야 비로소 통일된 해석을 시작했다.

 

 무슨 이야기일까?

 

 다시 한번 숨을 가다듬고 생각해보자. 이 알 수 없는 우리 눈앞에 보이는 예컨데 "공", 다시 말하자면 "질량"이라는 것은 무엇일까?

 

 손으로 잡은 후, 멀리 던지면 땅에 떨어지는 이 무언가에 대한 이야기다. 가만히 생각해보면 우리는 이 존재를 아래 두가지로 인지할 수 있다는 것을 경험상 알고 있다(그리고 이는 뉴튼이 맨 처음 수학적으로 정리한 형태이기도 하다)

 

1. 밀거나 멈추는데 힘이 들어간다(F = ma, 관성질량)

2. 두 질량이 있는 존재는 서로 당긴다(뉴튼의 중력 계산, F = G * m1 * m2 / r^2, 그래서 지구쪽으로 떨어진다. 중력질량)

 

 그리고 당연히 인류는 아인슈타인 이전까지 이 둘을 이렇게 서로 다른 것으로 정의해서 사용하였다. 어떤 이들에게는 사실 같아 보이는데, 사실은 전혀 다른 것이라는 것을 알 수 있다. 어떻게 해도 둘을 같게 해석할 수가 없다. 공을 빠르게 하는데 힘이 들어간다는 사실이, 두 공이 서로 당긴다는 사실과 연관짓기가 힘든 것이다.

 

 이는 물리학자들에게 각기 관성질량과 중력질량으로 구분되었고, 초기에는 이 둘이 같다는 여러가지 증명하려는 시도가 있었다. 피사의 사탑에서 무거운 공과 가벼운 공을 낙하시키는 실험이 그렇다. 중력과 가속도가 동시에 반영되는 상황에서는 그래서 질량에 상관없이 동일한 운동을 보인다. 공기가 없는 와중에 포물선을 그리며 날아가는 공도 그러하다. 그것들은 본래의 질량과 관련이 없다. 관성 질량과 중력 질량은 마치 동일한 것처럼 작동한다는 사실에 늘 과거의 물리학자들은 의아해했다.

 

 그런데 이 둘을 합쳐서 생각해볼 수 있는 방식이 존재한다. 그것은 대체 어떤 것일까? 가속하기 어렵다는 사실과 두 질량이 서로를 당긴다는 사실을 어떻게 하나의 원리로 바라볼 수 있을까?

 

여기에 아인슈타인이 주장했던 등가 원리(equivalance principle)는 그 중요한 열쇠가 된다. 즉, 엘레베이터 안에 갇혀있어서 밖을 볼 수 없는 상황에서는 이 두가지를 구별할 수 없다는 이야기다.

 

 밖에서 엘레베이터를 누가 밀어서 가속하면, 그 안의 내가 뒤로 밀릴텐데 이것이 가속에 의한 것인지, 아니면 지구같은 어떤 큰 질량이 옆에 있어서 중력에 의해 그렇게 되는지 알 수 없다는 사실이다. 이것이 바로 아인슈타인의 깨달음이며 등가원리의 기본이다. 그 둘을 구별할 수가 없다. 질량의 존재가 가속을 방해하거나 질량끼리의 당기는 힘을 만들어내면 된다.

 

 어떻게 이런 것이 가능할까? 놀랍게도 바로 질량이라는 것이 시공간을 휘면 그렇게 된다. 특수 상대성이론 등 여러가지 속에 그 기초를 닦은 아인슈타인은 그렇게 이 질량을 바라보는 시각을 혁신했다.

 

 그렇다. 질량은 시공간을 휜다. 그렇게 두 질량이 시공간을 휘면 서로에게 다가가려고 하는 방향으로 움직인다. 그것이 가장 자연스러운 상태이기 때문이다. 홀로 있을때는 어떠한가, 시공간이 휘면서 질량은 스스로를 감가속이 없는 상태로 유지하고자 하기 때문에(자기 스스로에게 낙하) 가속에는 힘이 들게 된다. 질량이 단독으로 존재 할 때도, 여러 질량이 같이 있을때도, 시공간의 휘어진 형상은 이 질량은 가속하기 어렵게 또한 서로에게 당겨지도록 하는 힘의 장을 만들어낸다. 아인슈타인의 장 방정식(Field Equation)이다.

 

 아래의 계량 텐서는 각 공간의 구조를 결정짓고, 이는 각 요소들간의 미분관계를 담는 리치 텐서와 질량/에너지의 분포를 다룬 스트레스-에너지 텐서를 통해 결정된다.

아인슈타인 장 방정식, 나무위키 발췌, 다양한 형태가 존재한다. 질량으로 인한 휘어진 시공간을 미분으로 나타낸다.

 

 이렇게 통합되어 설명하고 나면, 시공간의 휘어짐이 임계치를 넘는 블랙홀이라던가, 거대 질량 주변의 시간이 느리게 간다던가 하는 효과를 모두 계산할 수 있게 되었고, 지금은 관성질량/중력질량으로 구분해서 이해하던 시기보다도 훨씬 더 대규모의 자연 현상을 정확하게 계산할 수 있게 된 것이다.

 

 즉 관성질량과 중력질량이라는 두가지 관점을 장방정식으로 풀어낸 것이 아인슈타인의 업적이 되겠다. 서로 다른 두개를 하나의 틀에서 볼 수 있게 되자 기존의 상황이 더 명확해졌고, 훨씬 더 극단적인 상황에서의 예측이 가능해지게 된 것이다.그곳에는 공간의 휨뿐만 아니라 시간까지도 고려되어야 한다는 것이 그의 결론이 된 셈이다. 그렇게 그의 업적을 바라볼 수가 있다. 인류 역사의 기록에 남겨진, 기막힌 통찰의 순간 중의 하나이다. 우리가 향후에 또다른 통합된 이론을 가지게 된다면 왜 그때는 이것이 서로 같다는 것을 몰랐을까 라고 한탄할 주제에 대한 사전 예시가 아닌가.

 

 장방정식 관련해서는 아래 차동우 교수의 짧은 강의를 참고해보자.

https://www.youtube.com/watch?v=E3o1KahfWMw&t=1204s

 

반응형
Posted by 작동미학