iT邦幫忙

2025 iThome 鐵人賽

DAY 3
0
生成式 AI

阿,又是一個RAG系列 第 3

Day2-RagDatasetGenerator

  • 分享至 

  • xImage
  •  

Result

首先是今天的結果:

  {

    "query":"老師為何在課程中仍保留需要花三到四個小時訓練的作業?這類作業想讓學生>體驗什麼?老師對「三四個小時」的訓練時間與需要數天或數週訓練的情況有何看法?",

    "reference_contexts":[

      "業設計成這樣呢\n為什麼作業要跑三個小時呢\n我只允許這個作業三分鐘\n就應該要>跑完\n我們有當然可以把這些特別花時間\n需要特別花時間訓練的作業拿掉\n但是我還是選>擇在這門課裡面\n保留那一些\n需要一定訓練時間的作業\n因為焦躁的等待人工智慧訓練的結果\n迷茫的調參數\n不知道會不會成功\n這個就是人工智慧的醍醐味\n所以大家需要學習\n在迷茫中前進\n這個就是模型的訓練\n我們特別把這一部分保留在課程裡面\n讓你體驗說\n模型訓練不出來的焦躁\n到底是什麼樣的感覺\n而且我必須要強調啊\n什麼三四個小時的等待訓練時間\n真的不算什麼\n我們過去有很多作業訓練時間都是\n至少三天起跳\n你要至少訓練三天\n你才能夠拿到成績\n那我知道說很多同學在做作業的時候\n往往你都在實現\n最後一天才開始做作業\n但那一種啊\n需要訓練三天以上的模型\n你只在前一天才開始做作業\n你是絕不可能完成的\n這個時候我告訴你\n你唯一可以做的事情\n就是放棄這樣子\n還好我們這堂課裡面呢\n現在是沒有需要訓練一天以上的作業啦\n我們把那種\n特別需要花時間訓練的作業\n還是拿掉了\n只保留了需要訓練三四個小時的作業\n但我只想要強調說\n三四個小時的訓練時間\n真的不算什麼\n如果你要真正用大量的資料\n大規模的訓練模型\n訓練個數週\n其實都是常見的事情\n而這一些\n需要一點訓練時間的作業\n它的定位就像是預防針\n幫助你在未來面對更大的挑戰\n幫助你在未來面對挑戰的時候\n做好心理準備\n另外呢\n鼓勵大家如果有空的話\n可以先看一些線上的錄影進行預習\n那假設你對於生成式AI一無所知的話\n那你可以先看生成式AI導論2024的課程\n那如果2024的課程看完\n你想要進一步了解\n這些AI是怎麼被訓練出來的"

    ],

    "reference_answer":"",

    "reference_answer_by":"None",

    "query_by":"ai (gpt-5-mini)"

  },
  • 主要的input是reference_contexts,是我們昨天從youtube抓下來的字幕(整個字幕檔案叫document)切出來的片段(reference_context)叫nodes

  • 從query_by可以看到用的是gpt-5-mini

  • 生成的問題就是query,雖然我私心更希望這題應該問的是"什麼是人工智慧的醍醐味?"

  • 接下來就交代一下這是怎麼做的吧。

Situation:

  • 我們想要替RAG系統獲得成對的(context, question, answer)供後續方法論的驗證
  • 在day1-get_context_from_YT我們已經從youtube url獲取了字幕,並存成txt檔

Task:

我們今天的目標是在給定txt檔的文本後,prompt llm 來把對應的問題生成出來

Action:

環境

我們今天用llama-index,然後先直接call chat-gpt,後面再看看要不要改用ollama

pip install llama-index-llms-openai
pip install llama-index
pip install python-dotenv

code

  1. 首先是把昨天的txt檔案讀進來做成 llama-index的documents
from llama_index.core import SimpleDirectoryReader
source_dir = '../data/'
reader = SimpleDirectoryReader(source_dir, required_exts=['.txt'])
documents = reader.load_data()
doc = documents[0]
doc.text[:10]

結果:

'各位同學大家好 我們'

因為我們的路徑下只有一個txt檔案,所以documents就只會有一個element,基本上就是把整個檔案讀進來。
2. 然後就是今天的主角RagDatasetGenerator

from llama_index.core.llama_dataset.generator import RagDatasetGenerator
from llama_index.llms.openai import OpenAI
# instantiate a DatasetGenerator
dataset_generator = RagDatasetGenerator.from_documents(
    documents,
    llm=llm,
    num_questions_per_chunk=1,  # set the number of questions per nodes
    show_progress=True,
)
  1. RagDatasetGenerator會自己幫我們切成node,來避免單一檔案文字太長的問題,用.nodes可以拿到它們
len(dataset_generator.nodes)

9

所以說整個文章被切成了9個nodes
4. 順便看一下預設是怎麼切的

for idx, node in enumerate(dataset_generator.nodes):
    print(node.text[0])
    print(f"idx: {idx}, beg: {node.start_char_idx}, end: {node.end_char_idx}")

結果:


idx: 0, beg: 0, end: 720

idx: 1, beg: 721, end: 1527
t
idx: 2, beg: 1436, end: 2255
c
idx: 3, beg: 2256, end: 3003
C
idx: 4, beg: 2869, end: 3277
C
idx: 5, beg: 3231, end: 4015
C
idx: 6, beg: 3882, end: 4612

idx: 7, beg: 4482, end: 5182

idx: 8, beg: 5038, end: 5264

  1. 看一下上面的index跟原始的文檔對不對的起來
doc.text[721]

'第'

wow! 所以他預設是沒有overlap的切。

  1. 然後就是questions的生成
questions = dataset_generator.generate_questions_from_nodes()

結果完全不work...

{

    "query":"請回答下列題目(作答請分項清楚標示):",

    "reference_contexts":[

      "第一種\n如果你未來想要更深入人工智慧領域\n這門可絕對是很好的入門\n當然要完全掌握AI這門課還不夠深\n但它會是你AI旅程很棒的第一步\n希望不會是你的最後一步\n第二種\n即使你未來沒有要深入AI領域\n只是想要對這些工具有不一樣的認識\n本課程也很適合你\n它會讓你用更有智慧的方式\n來使用這些AI工具\n那什麼樣的同學不適合呢?\n如果你已經有訓練模型的經驗\n本課程對你來說可能會太淺了\n另一方面\n如果你完全沒有使用過ChetGPT或類似的人工智慧\n完全不知道ChetGPT是什麼\n那本門課對你來說可能會挑戰太大\n但如果你對於ChetGPT已經有使用經驗\n就算不會寫程式\n我會盡力讓每個人都能跟上\n我相信在這個AI時代\n每個人都應該有機會了解這些改變世界的技術\n那這邊講到一個段落\n我們換一下投影片\n今天深層式人工智慧真的是無所不在\n最後我想說的是\n到目前為止\n其實所有的內容都是人工智慧生成的\n身為人類的李宏毅老師\n到目前為止都還沒出場\n讓我們歡迎真正的李宏毅老師出場\n好 各位同學大家好啊\n我是身為人類的李宏毅\n那剛才你看到的所有內容\n真的都是人工智慧產生的\n那最開場你看到的那個倒數計時的影片\n還有變成鳥人想要飛走卻飛不走的影片\n那個都是用Google的VO3生成的\n那VO3做的事情就是給他一段文字的敘述\n比如說我就說\n我要產生一個倒數計時的影片\n他就給我一個倒數計時的影片\n那有很多事情你可能不容易用文字描述\n所以VO3也支持給他一張照片\n比如說我給他一個我在演講的照片\n然後我說要讓這個人介紹某一門課程\n要讓這個人長出翅膀\n那VO3就可以根據我的敘述\n還有我給他的照片產生對應的影片\n那英文的那個聲音\n我說Introduction to this course\n這個也是VO3自己生成的\n他產生的影片是帶有聲音的\n那其他中文講課的聲音也通通都是合成的\n我是用Eleven Labs這個軟體合成的\n我是用Eleven"

    ],

    "reference_answer":"",

    "reference_answer_by":"None",

    "query_by":"ai (gpt-5-mini)"

  },

 7. 這邊就直上到最後work的版本(V4)了:

 text_question_template = """以下是上課內容片段:
---------------------
{context_str}
---------------------
{query_str}
"""

question_gen_query = """你的任務是為根據所提供的上課內容片段,設計 1 題問題來問學生。  
問題應該涵蓋文件中的多樣化主題,並且需要在上課內容片段中找的到答案。
範例輸出:
什麼是深度學習的醍醐味?
"""

dataset_generator_v4 = RagDatasetGenerator.from_documents(
    documents,
    llm=llm,
    num_questions_per_chunk=1,  # set the number of questions per nodes
    text_question_template = PromptTemplate(text_question_template),
    question_gen_query = question_gen_query,
    show_progress=True,
)

 8. 這邊是各版本的修正紀錄:

  • v2: 把預設的中文prompt改成英文prompt
    首先我去確認了切出來的context是不是真的可以拿來出題,結論是個人認為完全可行,720個中文字的短文要做個閱讀測驗是綽綽有餘的,所以我就懷疑是英文prompt的問題,但結果還是一樣
  • v3: 更好的prompt
    這邊就直接看一下v2 跟 v3 prompt的比對,其中v2是直接把default prompt用chatgpt翻譯成中文的結果,v3是人工修改了一些表達方式,我感覺是生硬的翻譯描述太複雜讓model誤會,結果,還是都不work!,一樣大部分都是生成諸如: "query":"請回答下列問題(可分點作答):",這樣的問題。
    可以看到說prompt其實都是很簡單的。
## v2
text_question_template = """以下是情境資訊:
---------------------
{context_str}
---------------------
請僅根據上述情境資訊(而非先驗知識),
依照下方查詢生成問題。
{query_str}
"""

question_gen_query = """你是一位老師/教授。你的任務是為即將到來的測驗/考試,根據所提供的內容資訊,設計 1 題考題。  
考題應該涵蓋文件中的多樣化主題,並且僅限於給定的情境資訊。"""
## v3
text_question_template = """以下是上課內容片段:
---------------------
{context_str}
---------------------
{query_str}
"""

question_gen_query = """你是一位老師/教授。你的任務是為根據所提供的上課內容片段,設計 1 題問題來問學生。  
問題應該涵蓋文件中的多樣化主題,並且需要在上課內容片段中找的到答案。"""
  • v4: 加上few-shot,不過嚴格來說這也不算是few-shot,因為只有給範例輸出
text_question_template = """以下是上課內容片段:
---------------------
{context_str}
---------------------
{query_str}
"""

question_gen_query = """你的任務是為根據所提供的上課內容片段,設計 1 題問題來問學生。  
問題應該涵蓋文件中的多樣化主題,並且需要在上課內容片段中找的到答案。
範例輸出:
什麼是深度學習的醍醐味?
"""

然後就得到了最一開始的結果

  1. 最後我們把產生的題目存出去
df = questions_v4.to_pandas()
df.to_json(
    "question_v4.json",
    orient="records",
    force_ascii=False,
    indent=2
)

這邊有一個小坑是他其實自帶一個method是save_json,但是只接受path參數,那在裡面有中文的情況下存出去的檔案就沒辦法點開來看,所以這邊就轉成dataframe再存json

Summary:

  • 我們今天主要用了llama-index的RagDatasetGenerator來把document轉成query
    • 他裡面自帶了把document切成node,預設沒有overlap,約720字一個node
    • 裡面其實就是prompt llm 去把context 生成 k 個問題
    • 預設的英文prompt要直接生成合適的問題結果會不work,最後是加上了fewshot結果才符合預期
  • 真的把課程內容逐段拿來生成問題,就算問題質量也許不高,看到的當下還是覺得相當的震驚

其他

  • RagDatasetGenerator的前身是QuestionGeneration,不過你現在如果用QuestionGeneration會跳deprecated warning
  • 找的到一大堆cookbooks用QuestionGeneration來示範RAG的evaluation
  • 後面應該可以寫個一篇把長文分段的方法,總是要面對這個問題
  • 然後我們需要兜個工具可以看到每次這樣呼叫到底調用了哪些東西

Reference:


上一篇
Day1-get_context_from_YT
系列文
阿,又是一個RAG3
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言