structured_output_dataset.json
"3.依《靈樞.經脈》所記載:「是主筋所生病者,痔、瘧、狂、癲疾、頭顖、項痛,目黃、淚出,鼽\n衄,項、背、腰、尻、膕、腨、腳皆痛,小趾不用」,指何經的病證內容?\n \nA.膀胱經\nB.膽經\nC.三焦經\nD.脾經"
"qid": "3",
"stem": "依《靈樞.經脈》記載,\"其直者,從巔入絡腦,還出別下項,循肩膊內,挾脊抵腰中\",\n指下列\n何經的循行內容?\n\n"
"A": "膀胱經",
"B": "膽經",
"C": "胃經",
"D": "肝經",
class MCQ(BaseModel):
"""單選題結構,包含題號(qid)、題幹(stem)、以及 A、B、C、D 四個選項"""
qid: int = Field(..., description='題號')
stem: str = Field(..., description='題幹')
A: str = Field(..., description="本題的A選項")
B: str = Field(..., description="本題的B選項")
C: str = Field(..., description="本題的C選項")
D: str = Field(..., description="本題的D選項")
ans: Optional[str] = Field(default=None, description='答案')
首先針對 llama,我們直接調用 llama-index 封裝的 structured LLMs
sllama=llama.as_structured_llm(Pydantic)
{'qid': 1,
'stem': '答案是 C',
'A': '上星、日月',
'B': '合谷、太衝',
'C': '內關、外關',
'D': '上關、下關',
'ans': None}
接著,我們調用 llama-index 封裝的 structured_predict
response = llama.structured_predict(Pydantic, prompt, text=query)
structured LLMs
的基礎上可以讓我們進一步客製 prompt
structured LLMs
底下也是調用 structured_predict
"Extract an MCQ from the following text. If you cannot find an answer, use the default value None and the date as the invoice ID: {text}"
prompt_en_llama
: "Extract a multiple-choice question (MCQ) from the following text. If the original text does not provide an answer, omit the answer field entirely and do not attempt to guess it: {text}"
{'qid': 1,
'stem': '',
'A': '上星、日月',
'B': '合谷、太衝',
'C': '內關、外關',
'D': '上關、下關',
'ans': None}
下一步,我們把 prompt 從本來的英文,要求 chatgpt 翻譯為中文
prompt_zh_llama
: "從以下文字中擷取一題選擇題 (MCQ)。如果原始文字沒有提供答案,則完全省略答案欄位,且不要嘗試推測答案:{text}"
{'qid': 1,
'stem': '常見針灸配穴法中,所指的「四關穴」,為下列何穴位之組合?',
'A': '上星、日月',
'B': '合谷、太衝',
'C': '內關、外關',
'D': '上關、下關',
'ans': None}
此外,我們還有請 chatgpt 幫我們寫了一份落落長的 prompt := prompt_gpt_llama
- 點我看
- 大致上就是:角色扮演、嚴格規則、Few-shot、反覆強調
鏡頭一轉我們把目光聚焦在 gemma 上
prompt_gemma = PromptTemplate(
"這是 MCQ 的 JSON schema:\n"
f"{schema}\n"
"從以下文字中擷取一題選擇題 (MCQ)。如果原始文字沒有提供答案,則完全省略答案欄位,且不要嘗試推測答案\n\n以下開始:\n"
"-----\n"
"{text}\n"
"-----\n"
"結果:\n"
)
prompt_zh_llama
人工加上 schema\```json
{
"qid": 1,
"stem": "常見針灸配穴法中,所指的「四關穴」,為下列何穴位之組合?",
"A": "上星、日月",
"B": "合谷、太衝",
"C": "內關、外關",
"D": "上關、下關"
}
\```
然後我們把json_mode開起來,呼叫 json_gemma
{
"qid": 1,
"stem": "常見針灸配穴法中,所指的「四關穴」,為下列何穴位之組合?",
"A": "上星、日月",
"B": "合谷、太衝",
"C": "內關、外關",
"D": "上關、下關"
}
llm = Ollama(model=model_name, json_mode=json_mode)
additional_kwargs={'response_format': {"type": "json_object"}})
到這邊我們對實驗結果大概有了一些預期
上面所有的程式碼都可以在 notebook 找的到
我們會一題一題的呼叫我們的各選手,並且把答案存出來
選手清單:
想法:
測試環境為筆電的 5070
目前跑完大致看到的結果如下:
llama + prompt_en: 因為 Timeout 直接 miss 了 7 題
llama + prompt_zh: 同樣因為 Timeout miss 了 7 題
llama + prompt_gpt: 這個 prompt 最長,卻沒有任何miss
json_gemma + prompt_gemma:
gemma + prompt_gemma:
predict: 來人工看結果
今天就這樣啦,這場比賽究竟鹿死誰手讓我們繼續看下去