Siri Belajar AI : Buat RAG dari kosong (Bahagian Akhir)
Akhirnya, kita sudah tiba di bahagian yang terakhir. Bahagian yang paling penting sekali. Dalam bahagian ini, kita akan cuba untuk memuat turun model AI kita sendiri, dan menjalankannya pada dokumen-dokumen yang kita ada.
Sebagai pengenalan, anda semua mungkin kenal pada ChatGPT. ChatGPT merupakan aplikasi yang paling pantas berkembang ketika ia dilancarkan. Aplikasi AI ini yang membolehkan manusia berinteraksi secara natural pada AI benar-benar mengejutkan ramai orang dan meletupkan minda sesiapa yang menggunakannya. Dianggarkan sehingga Mac 2024, ChatGPT digunakan oleh 180 juta pengguna di seluruh dunia.
Tapi kau orang jangan salah faham. Yang hebat itu bukan ChatGPT. ChatGPT hanyalah perisian depan yang berinteraksi dengan manusia. Yang hebatnya adalah model AI yang berdiri di belakang ChatGPT. Model yang dipanggil sebagai GPT.
Untuk yang menggunakan secara percuma, OpenAI menyediakan model GPT 3.5 Turbo. Untuk pengguna yang berbayar, OpenAI memberikan perkhidmatan model terikini dan tercanggih mereka, GPT 4.
Model Terbuka vs Model Tertutup (Open source vs Closed)
Apa yang ditawarkan oleh OpenAI selain dari ChatGPT adalah penggunaan model-model AI yang mereka ada. Dari GPT 3.5 , GPT 4 dan juga DALL-E, setiap model ini boleh diakses oleh mana-mana pengaturcara (developer) untuk membangunkan aplikasi AI mereka sendiri melalui API (application programming interface) yang disediakan. Namun begitu, setiap penggunaan akan dicaj, mengikut jumlah token yang diproses. Secara puratanya, OpenAI akan mengenakan bayaran dari $0.05 ke $30 bagi setiap jumlah token yang diproses. Kadar bayaran sebenarnya bergantung pada model mana yang akan digunakan.
Bagi mereka yang tidak mempunyai biaya yang banyak (seperti saya), ada alternatif-alternatif lain yang boleh digunakan. Yang paling utama sekali ada penggunaan model AI dari sumber terbuka (open source). Walaupun OpenAI ada perkutaan ‘open’ di depannya, tapi ia tidak lagi menawarkan model-model AI secara percuma. Sebaliknya, syarikat-syarikat seperti Meta, Google dan juga Microsoft ada menawarkan model-model AI mereka yang boleh diakses secara percuma oleh sesiapa sahaja, asalkan mereka ada kemahiran pengaturcaraan.
Itulah yang akan kita cuba buat untuk harini. Kita akan memuat turun satu model AI, dan menggunakannya dalam RAG pipeline kita.
HuggingFace, Tempat Berkumpulnya Open Source AI
Kebanyakan model-model AI open source ini boleh dimuat turun dari HuggingFace, hub komuniti pembina AI. HuggingFace menawarkan framework yang mudah bagi sesiapa sahaja untuk memuat turun model AI, dan menggunakannya dalam aplikasi masing-masing.
Untuk tutorial kita ni, kita akan menggunakan model keluaran Google, model yang dipanggil sebagai Gemma, yang baru sahaja dilancarkan pada Februari 2024 yang lalu.
Jika kita ke laman web Google, ada dua model Gemma yang disenaraikan. Gemma 2B dan juga Gemma 7B. B yang dibelakang itu mewakili 7 billion, membawa maksud berapa banyak parameter yang ada pada model AI tersebut. Secara ringkasnya, lebih banyak parameter, lebih hebatlah model AI tersebut. Tapi hipotesis ini tak terpakai untuk semua keadaan. Dalam kes kita, lebih banyak parameter, lebih beratlah model AI tersebut, dan lebih besar saiznya. Lebih banyak parameter juga membawa maksud lebih banyak kuasa komputer yang diperlukan untuk model AI itu melakukan inferens. Kerana itulah sebelum kita memuat turun, seeloknya kita periksa dulu kemampuan komputer kita.
Ukur baju di badan sendiri
Dari bahagian yang lepas, kita sudahpun menggunakan GoogleColab sebagai sumber komputasi kita. Dan GoogleColab sudahpun disertakan GPU mereka sendiri yang datang dari Nvidia. Jika para pembaca ada komputer yang mempunyai GPU Nvidia, anda semua boleh running code di bawah:
!nvidia-smiHasilnya akan terlihat kemas seperti di bawah:
Boleh dilihat di bawah, yang kita menggunakan GPU Tesla T4 dari Nvidia, yang datang dengan memori 15 GB. Tapi jika anda tidak mempunyai GPU dari Nvidia, anda boleh menjalankan kod di bawah pula:
#get gpu available memory
import torch
gpu_memory_bytes = torch.cuda.get_device_properties(0).total_memory
gpu_memory_gb = gpu_memory_bytes / (1024.0 ** 3)
print(f"Total GPU memory available: {gpu_memory_gb} bytes")Sekarang, kita sudah tahu GPU apa yang kita gunakan, dan berapa banyak memori yang ada pada GPU kita. Masa untuk memilih model yang sesuai untuk kita gunakan. Boleh sahaja jalankan kod di bawah:
# Note: the following is Gemma focused, however, there are more and more LLMs of the 2B and 7B size appearing for local use.
if gpu_memory_gb < 5.1:
print(f"Your available GPU memory is {gpu_memory_gb}GB, you may not have enough memory to run a Gemma LLM locally without quantization.")
elif gpu_memory_gb < 8.1:
print(f"GPU memory: {gpu_memory_gb} | Recommended model: Gemmab 2B in 4-bit precision.")
use_quantization_config = True
model_id = "google/gemma-2b-it"
elif gpu_memory_gb < 19.0:
print(f"GPU memory: {gpu_memory_gb} | Recommended model: Gemma 2B in float16 or Gemma 7B in 4-bit precision.")
use_quantization_config = False
model_id = "google/gemma-2b-it"
elif gpu_memory_gb > 19.0:
print(f"GPU memory: {gpu_memory_gb} | Recommend model: Gemma 7B in 4-bit or float16 precision.")
use_quantization_config = False
model_id = "google/gemma-7b-it"
print(f"use_quantization_config set to: {use_quantization_config}")
print(f"model_id set to: {model_id}")Kerana saiz memori yang di bawah 19.0 GB, model yang sesuai digunakan adalah model Gemma dengan 2 billion parameter. Satu lagi yang kau orang perlu tahu adalah, ada juga model-model yang telah di’quantize’ kan, atau dalam bahasa mudahnya dikecilkan. Sama ada dalam bentuk 8-bit atau 4-bit. Tapi ini juga bermakna ketepatan model AI itu akan berkurang. Tapi kalau hanya nak cuba-cuba sahaja bolehlah pakai model yang dah diquantizekan ni. Kalau nak baca lebih lanjut pasal quantization, boleh baca kat sini:
Quantization
We're on a journey to advance and democratize artificial intelligence through open source and open science.huggingface.co
Ok, sekarang masanya untuk memuat turun model kita. Cara untuk memuat turun setiap model AI ada diperincikan dalam model card HuggingFace hub, untuk model Gemma-2b-it, boleh lihat di bawah
google/gemma-2b-it · Hugging Face
We're on a journey to advance and democratize artificial intelligence through open source and open science.huggingface.co
Ok, tapi kita perlu install dulu beberapa library dan package tambahan. Pastikan juga anda mempunyai akaun HuggingFace dan juga sudah mengaktifkan accesstoken dari HuggingFace
!pip install transformers
!pip install bitsandbytes
!pip install flash-attn --no-build-isolation
!pip install accelerateSeterusnya anda boleh login ke huggingface dengan access token yang sudah digenerate. Access Token boleh didapati dari Settings>Access Tokens
!huggingface-cli loginDan masukkan token ke bawah ini:
Selepas itu, anda sudah boleh memuat turun model AI sendiri dengan kod di bawah:
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
from transformers.utils import is_flash_attn_2_available
#1. Quantization
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True,
bnb_4bit_compute_dtype=torch.float16)
#bonus : flash attention 2 = faster attention mechanism
if (is_flash_attn_2_available()) and (torch.cuda.get_device_capability(0)[0]>= 8):
attn_implementation = "flash-attention-2"
else:
attn_implementation = "sdpa"
#2. Model ID
model_id = "google/gemma-2b-it"
#3. Initiate tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_id)
#4. Instatiate the model
llm_model = AutoModelForCausalLM.from_pretrained(model_id,
torch_dtype=torch.float16,
quantization_config=quantization_config if use_quantization_config else None,
low_cpu_mem_usage=False,
attn_implementation=attn_implementation)
if not use_quantization_config:
llm_model.to("cuda")Ok, kita dah model ada LLM kita sendiri. Kalau kita tengok pada model LLM kita, kita boleh secara asasnya struktur yang ada
llm_modelSekarang, kita nak gunakan model AI yang baru sahaja kita muat turun ini untuk generate sesuatu. Macam kita nak buat kita punya ChatGPT sendiri. Benda pertama sekali yang kita perlu faham adalah, setiap model AI ini mempunyai format yang tersendiri untuk menerima input. Kita tak boleh terus memasukkan soalan kepada model AI kita untuk bertanya soalan. Kita perlu pastikan format soalan itu betul. Boleh salin kod di bawah:
input_text = "What is attention-mechanism?"
print(f"Input text:\n{input_text}")
#create prompt template for instruction tuned model
dialogue_template = [
{"role":"user",
"content":input_text}
]
#apply the chat template
prompt = tokenizer.apply_chat_template(conversation=dialogue_template,
tokenize=False,
add_generation_prompt = True)
print(f"Prompt:\n{prompt}")Dan bila kita jalankan kod tersebut, hasilnya boleh dilihat seperti di bawah:
Boleh dilihat di atas yang input yang kita masukkan itu telah disusun dengan penanda seperti , <bos> ,<start_of_turn> dan banyak lagi. Ini memberikan kefahaman pada model AI untuk memberikan jawapan.
Ok ,sekarang kita boleh tanyakan soalan kita ni pada model AI kita.
#tokenize input text
input_ids = tokenizer.encode(prompt,
return_tensors="pt").to("cuda")
#generate outputs from local LLM
outputs = llm_model.generate(input_ids,
max_new_tokens=256)
#decode the outputs
outputs_decoded = tokenizer.decode(outputs[0])
print(f"Model output (text)\n{outputs_decoded}\n")Dan hasilnya terlihat seperti di bawah:
Alhamdulillah. Akhirnya kita berjaya menjalankan model kita sendiri, secara lokal. Ok, sekarang kita dah bersedia untuk ke bahagian akhir
Memperkuatkan (Augment) Prompt Kita
Sekarang kita berada di bahagian augmentation dalam RAG pipeline kita. Bahagian yang nampak macam mudah, tapi sebenarnya sukar. Dalam bahagian ini kita cuma perlu memberi konteks pada model LLM kita supaya jawapan yang diberikan oleh mereka lebih tepat dan bersesuaian dengan konteks yang diberi.
Kita berikan satu contoh mengikut teks yang kita gunakan dalam RAG pipeline kita. Kalau kita tengok tangkap layar di bawah, dalam API 521 2022, maksud perkataan ‘lift-off’ adalah:
Tapi bila kita tanya pada ChatGPT apa maksud ‘lift-off’ menurut API 521 2022, dia memberi jawapan seperti di bawah:
Nampak tak dia memandai je bagi jawapan. Ini disebabkan ChatGPT dilatih dengan data umum. Ia tak dilatih pada data spesifik yang kita perlukan. Kerana itulah kita perlu memberi konteks pada model AI supaya dia boleh memberikan jawapan yang lebih tepat.
Untuk buat augmentation ni, kita perlu ada sedikit kemahiran prompt engineering. Benda ni masih lagi baru, dan belum ada cara yang betul-betul tepat. Ada yang kata prompt engineering ni macam seni, dan bukan sains yang spesifik. Kalau anda nak baca pasal prompt engineering, boleh baca kat sini:
https://www.promptingguide.ai/introduction/tips
Untuk kali ni, kita cuma buat prompting yang mudah sahaja, boleh salin kod di bawah:
def prompt_formatter(query: str,
context_items: list[dict]) -> str:
"""
Augments query with text-based context from context_items.
"""
# Join context items into one dotted paragraph
context = "- " + "\n- ".join([item["sentence_chunk"] for item in context_items])
# Create a base prompt with examples to help the model
# We could also write this in a txt file and import it in if we wanted.
base_prompt = """Based on the following context, please provide the the answer to the query
Context: {context}
Query: {query}
Answer:"""
# Update base prompt with context items and query
base_prompt = base_prompt.format(context=context, query=query)
# Create prompt template for instruction-tuned model
dialogue_template = [
{"role": "user",
"content": base_prompt}
]
# Apply the chat template
prompt = tokenizer.apply_chat_template(conversation=dialogue_template,
tokenize=False,
add_generation_prompt=True)
return promptApa yang kita buat adalah kita susun prompt kita dalam bentuk di atas. Kita berikan LLM kita konteks yang kita cari melalui semantic search, dan konteks itu akan diproses oleh LLM untuk memberikan jawapan yang lebih tepat.
Kalau kita gunakan fungsi di atas, dan masukkan dalam soalan kita, jawapan yang diberikan akan lebih tepat.
import random
# Set a higher temperature value for more creative outputs
temperature = 1.0
query = random.choice(query_list)
# Get relevant resources
scores, indices = retrieve_source(query=query, embeddings=embeddings)
# Create a list of context items
context_items = [pages_and_chunks[i] for i in indices]
# Format prompt with context items
prompt = prompt_formatter(query=query, context_items=context_items)
input_ids = tokenizer(prompt, return_tensors="pt").to("cuda")
# Generate an output of tokens
outputs = llm_model.generate(**input_ids,
temperature=temperature,
do_sample=True,
max_new_tokens=256)
# Turn the output tokens into text
output_text = tokenizer.decode(outputs[0])
# Print the generated answer
print(f"Query: {query}")
print_wrapped(f"RAG answer:\n{output_text.replace(prompt, '')}")Hasilnya:
Nampak tak, bila ditanya apa maksud ‘lift-off’ berdasarkan konteks yang diberikan, jawapan yang diberikan tak lagi melalut.
Ok, itu sahajalah tutorial aku untuk RAG. Pada siri yang akan datang, kita akan belajar tentang asas AI itu sendiri. Mungkin kita akan bermula dengan perceptron, ataupun terus pada tokenization. Mungkin pembaca boleh terus komen, apa yang pembaca ingin tahu lebih lanjut tentang AI.











