NVlabs FVRuleLearner: การใช้ต้นไม้การอนุมานตัวดำเนินการเพื่อยุติข้อผิดพลาดด้านเวลาในการเขียน SystemVerilog Assertions ของ LLM ความแม่นยำในการตรวจสอบรูปแบบเพิ่มสูงขึ้น

การใช้โมเดลภาษาขนาดใหญ่ (LLM) เพื่อแปลงคำอธิบายภาษาธรรมชาติเป็น SystemVerilog Assertion (SVA) โดยผิวเผินแล้วเป็นสาขาหนึ่งของ “การสร้างโค้ด” แต่ความท้าทายที่แท้จริงไม่ใช่ไวยากรณ์ แต่เป็นความหมาย (Semantics) ตัวอย่างเช่น ข้อกำหนดที่ว่า “ต้องตอบสนองหลังจากจับมือกัน” อาจเกี่ยวข้องกับการเลือกตรรกะที่ละเอียดอ่อนหลายอย่าง เช่น การนัยเชิงเวลา (temporal implication) การปิดกั้นสัญญาณรีเซ็ต ความเสถียรของสัญญาณ หน้าต่างหน่วงเวลา และนามธรรมระดับบิต

งานวิจัยเผยให้เห็นว่า ในงาน Natural Language to SVA (NL-to-SVA) ข้อผิดพลาดด้านฟังก์ชันมากกว่า 80% เกิดจากการใช้ตัวดำเนินการเชิงเวลา (temporal operators) ผิดวิธี โดยเฉพาะอย่างยิ่ง ความสับสนระหว่างตัวดำเนินการ |-> และ |=> เพียงสองตัวนี้ทำให้ assertion ใช้ไม่ได้ผลถึง 50% ถึง 64% ข้อผิดพลาดประเภทนี้มีความคล้ายคลึงกันสูงในระดับข้อความ แต่กลับให้ผลลัพธ์การตรวจสอบเชิงรูปแบบ (formal verification) ที่ตรงกันข้ามโดยสิ้นเชิง

เมื่อเผชิญกับงาน NL-to-SVA การอนุมานทั่วไปของ LLM มักจะสร้าง SVA ที่มีข้อผิดพลาดด้านฟังก์ชัน เฟรมเวิร์ก FVRULELEARNER จาก NVlabs ใช้แนวทางที่แตกต่าง โดยสร้าง SVA ที่ถูกต้องตามฟังก์ชันผ่านแผนผังการอนุมานตัวดำเนินการ (OP-TREE) ที่เรียนรู้ได้ รูปภาพด้านล่างแสดงให้เห็นถึงความแตกต่างระหว่าง LLM ทั่วไปกับ FVRULELEARNER ในการสร้าง SVA โดยชี้ให้เห็นถึงปัญหาข้อผิดพลาดด้านฟังก์ชันของ LLM ในงาน NL-to-SVA ซึ่งเกิดจากความเข้าใจที่ไม่เพียงพอเกี่ยวกับตัวดำเนินการเชิงเวลาและข้อมูลการฝึกอบรมที่จำกัด LLM ทั่วไปไม่สามารถจับคู่ความหมายเชิงเวลาของฮาร์ดแวร์ได้อย่างแม่นยำ ในขณะที่ FVRULELEARNER อาศัยการอนุมานเชิงโครงสร้างของแผนผังการอนุมานตัวดำเนินการ ยึดโยงกับตรรกะการใช้งานที่ถูกต้องของตัวดำเนินการ SVA และแก้ไขปัญหาความไม่ตรงกันของฟังก์ชันตั้งแต่ต้นตอ สิ่งนี้ยืนยันคุณค่าหลักของ OP-TREE ในการปรับปรุงความถูกต้องของฟังก์ชัน SVA และยังเป็นรากฐานของนวัตกรรมทางเทคนิคของเฟรมเวิร์กนี้

เมื่อ LLM เขียน |-> ผิดเป็น |=> หรือละเว้นเงื่อนไข enable บางอย่าง แม้ว่าความคล้ายคลึงกันของข้อความอาจยังสูงอยู่ แต่ผลลัพธ์ของการตรวจสอบเชิงรูปแบบจะแตกต่างกันอย่างมาก

  • FVRULELEARNER: Operator-Level Reasoning Tree (OP-TREE)-Based Rules Learning for Formal Verification
  • FVRuleLearner คือไปป์ไลน์การเรียนรู้กฎสำหรับ NL2SVA เวอร์ชันหลักที่เผยแพร่ในปัจจุบันคือเส้นทางแบบ prompt-only ในไดเรกทอรี src และใช้ JasperGold ในการประเมินไวยากรณ์และฟังก์ชัน
  • โค้ด: https://github.com/NVlabs/FVRuleLearner
  • บทความ: https://arxiv.org/abs/2604.03245

คุณค่าหลักของ NVlabs/FVRuleLearner คือการเปลี่ยนตัวอย่างที่ล้มเหลวจากข้อผิดพลาดครั้งเดียว ให้กลายเป็นสินทรัพย์กฎที่สามารถนำไปค้นหา จัดลำดับ อธิบาย และนำกลับมาใช้ใหม่ได้ในภายหลัง

ภาพรวมของกระบวนการ FVRULELEARNER และตัวอย่างของ OP-TREE ระหว่างการฝึกอบรมแสดงอยู่ในรูปด้านล่าง รูปภาพนี้แยกย่อยกระบวนการหลักสองขั้นตอนของการฝึกอบรมและการทดสอบของ FVRULELEARNER: ขั้นตอนการฝึกอบรมจะจำลองตรรกะการดีบักของวิศวกรตรวจสอบผ่านโครงสร้างสามชั้นของ OP-TREE เพื่อกลั่นกรองร่องรอยการอนุมานตัวดำเนินการที่มีประสิทธิภาพ ขั้นตอนการทดสอบจะจับคู่ร่องรอยผ่านการค้นหาแบบผสมระหว่างตัวดำเนินการและความหมาย หลังจากปรับกฎแล้ว จะสร้าง Op-Rule สำหรับงานใหม่ OP-TREE ทำให้กระบวนการอนุมานสามารถอธิบายได้ แก้ปัญหากล่องดำของ LLM ในการสร้าง SVA ในขณะที่การออกแบบสองขั้นตอนช่วยรับประกันประสิทธิผลของกฎและความสามารถในการสรุปข้ามงาน

เฟรมเวิร์กนี้ไม่ได้เป็นเพียงการซ้อน prompt อย่างง่าย ๆ แต่เป็นการสร้าง OP-Tree สามชั้นในขั้นตอนการฝึกอบรม เจาะลึกถึงสาเหตุของข้อผิดพลาด ผ่านการวินิจฉัยบริบท การยึดโยงทางทฤษฎี และการสร้างกฎ เพื่อสร้างกฎระดับตัวดำเนินการที่ตรวจสอบได้ โดยคงไว้เฉพาะเส้นทางการอนุมานที่ JasperGold ยืนยันว่ามีฟังก์ชันเทียบเท่า ในขั้นตอนการอนุมานจะใช้กลไก RAG ที่ให้คะแนนแบบผสมระหว่างตัวดำเนินการและความหมาย ควบคู่กับการปรับกฎตามนามธรรมของสัญญาณ เพื่อสร้าง assertion ที่แม่นยำ

รูปภาพด้านล่างเปรียบเทียบผลกระทบของกฎทั่วไปกับกฎระดับตัวดำเนินการต่อการสร้าง SVA กฎทั่วไปเนื่องจากความเป็นนามธรรม ไม่สามารถแนะนำ LLM ให้ใช้ตัวดำเนินการเชิงเวลาได้อย่างแม่นยำ และสุดท้ายจะสร้าง assertion ที่มีข้อผิดพลาดด้านฟังก์ชัน ในขณะที่ Op-Rule ซึ่งเป็นคำสั่งที่ละเอียดและสามารถดำเนินการได้สำหรับตัวดำเนินการ SVA จะกำหนดสถานการณ์การใช้งานของตัวดำเนินการเชิงเวลาอย่างชัดเจน และขจัดความคลุมเครือทางความหมายโดยสิ้นเชิง การเปรียบเทียบนี้ยืนยันว่าความแม่นยำของกฎระดับตัวดำเนินการเป็นกุญแจสำคัญในการแก้ไขข้อบกพร่องด้านความหมายเชิงเวลาของ LLM และเป็นนวัตกรรมหลักที่ทำให้ FVRULELEARNER แตกต่างจากการเรียนรู้กฎแบบดั้งเดิม

ข้อมูลการทดลองแสดงให้เห็นว่า เมื่อเทียบกับ SOTA baseline เฟรมเวิร์กนี้มีความถูกต้องทางไวยากรณ์เพิ่มขึ้น 3.95% ความถูกต้องทางฟังก์ชันเพิ่มขึ้นโดยเฉลี่ย 31.17% และข้อผิดพลาดด้านฟังก์ชันของตัวดำเนินการต่างๆ ลดลงโดยเฉลี่ย 70.33% นอกจากนี้ ยังต้องการข้อมูลการฝึกอบรมเพียง 48% เพื่อให้ถึงจุดอิ่มตัวของประสิทธิภาพ และเปิดเผยชุดข้อมูลมาตรฐาน NL2SVA-OpenCore ที่มี 1,000 รายการจากการออกแบบฮาร์ดแวร์จริง

ตารางด้านล่างแสดงผลการทดลองของโมเดล LLM บนชุดทดสอบ NL-to-SVA สามประเภท เมื่อเปรียบเทียบ GPT-4o, Claude 4.5 Sonnet, o3-mini ภายใต้ baseline ต่างๆ และ FVRULELEARNER ในด้าน BLEU, ความถูกต้องทางไวยากรณ์, ความถูกต้องทางฟังก์ชัน ฯลฯ FVRULELEARNER มีประสิทธิภาพเหนือกว่าอย่างมากในทุกโมเดลและทุกชุดข้อมูล โดยความถูกต้องทางฟังก์ชันเพิ่มขึ้นโดยเฉลี่ย 31.17% และความถูกต้องทางไวยากรณ์ใกล้เคียง 100% ผลลัพธ์พิสูจน์ให้เห็นว่าเฟรมเวิร์กนี้ไม่พึ่งพา LLM เฉพาะเจาะจง มีความสามารถในการปรับใช้ได้ทั่วไปอย่างมาก และสามารถชดเชยข้อบกพร่องทางความหมายของ LLM ต่างๆ ในการสร้าง SVA ได้อย่างครอบคลุม

สารบัญ

  • หนึ่ง. การเริ่มต้นใช้งานอย่างรวดเร็ว
  • สอง. ปัญหาหลักที่โครงการต้องแก้ไข: การสร้าง SVA ไม่ใช่การแปล แต่เป็นการจัดตำแหน่งความหมายที่ตรวจสอบได้
  • 2.1 ช่องว่างทางความหมายจากภาษาธรรมชาติสู่ assertion เชิงรูปแบบ
  • 2.2 ภารกิจสามประเภทและจุดเริ่มต้นข้อมูล
  • สาม. สถาปัตยกรรมโดยรวม: การฝึกอบรมตกตะกอนกฎ การอนุมานค้นหากฎ การประเมินปิดลูปการตรวจสอบ
  • 3.1 จุดเริ่มต้นหลักคือเครื่องสถานะ
  • 3.2 การกำหนดค่าไม่ใช่สิ่งประกอบ แต่เป็นโปรโตคอลการทดลอง
  • สี่. Q-Tree: แยกข้อผิดพลาดครั้งเดียวเป็นเส้นทางการอนุมานที่เรียนรู้ได้
  • 4.1 ทำไมต้องเป็นต้นไม้ ไม่ใช่แค่ข้อความสะท้อน
  • 4.2 กระบวนการสร้าง Q-Tree
  • ห้า. RAG และการค้นหาเสริม: ไม่ใช่การหาคำตอบที่คล้ายกัน แต่เป็นการหาประสบการณ์การแก้ไขข้อผิดพลาดที่คล้ายกัน
  • 5.1 RAGAgent จัดระเบียบเอกสารอย่างไร
  • 5.2 จุดเริ่มต้นของการค้นหาเสริมด้วย Q-Tree
  • หก. การจัดเตรียม LLM: เส้นทางแบบเบาและเส้นทาง AutoGen อยู่ร่วมกัน
  • 6.1 FVProcessor คือตัวจัดตารางไปป์ไลน์
  • 6.2 กฎเข้าสู่ prompt อย่างไร
  • เจ็ด. ลูปปิด JasperGold: ข้อความที่เหมือนกันไม่ได้หมายความว่าฟังก์ชันถูกต้อง
  • 7.1 สคริปต์ Tcl กำหนดความหมายของการประเมินรูปแบบ
  • 7.2 ผลลัพธ์การประเมินถูกรวบรวมอย่างไร
  • แปด. ทรัพยากร SystemVerilog: testbench ไม่ใช่พื้นหลัง แต่เป็นจุดยึดทางความหมาย
  • 8.1 annotated_tb รองรับบริบทการตรวจสอบ
  • 8.2 ความพิเศษของเส้นทาง opencore
  • เก้า. ความรู้ถูกจัดเก็บอย่างไร: suggestions และ qtrees คือความทรงจำระยะยาวของโครงการ
  • 9.1 Q-Tree ถูกบันทึกในรูปแบบที่ทั้งเครื่องจักรและมนุษย์อ่านได้
  • 9.2 ความแตกต่างพื้นฐานจาก RAG ทั่วไป
  • สิบ. ข้อจำกัด ขอบเขต และสิ่งที่ควรนำไปปรับใช้
  • 10.1 ข้อจำกัดที่ต้องกล่าวถึงอย่างระมัดระวัง
  • 10.2 แรงบันดาลใจสำหรับระบบ AI+EDA
  • 10.3 หากเปรียบเทียบกับคอมไพเลอร์
  • บทสรุป: ความก้าวหน้าที่แท้จริงคือการทำให้ประสบการณ์การตรวจสอบเชิงรูปแบบสามารถสะสมได้

หนึ่ง. การเริ่มต้นใช้งานอย่างรวดเร็ว

เส้นทางหลักของโครงการและการเริ่มต้นใช้งานอย่างรวดเร็ว

เส้นทางหลักของ FVRuleLearner เวอร์ชันที่เผยแพร่ในปัจจุบันเป็นไปตามโหมด prompt-only ที่อธิบายไว้ใน README โดยจุดเริ่มต้นของโค้ดจะรวมอยู่ในไดเรกทอรี src/ ซึ่ง主要负责สามภารกิจหลัก: nl2sva_human, nl2sva_machine และ nl2sva_opencore ต่อไปนี้เป็นขั้นตอนมาตรฐานสำหรับการตั้งค่าสภาพแวดล้อมการทำงานอย่างรวดเร็ว:

# ที่มา: README.md  
conda create -n fvrulelearner python=3.10  
conda activate fvrulelearner  
pip install -r requirements.txt  

ก่อนเริ่มทำงาน ต้องกำหนดค่าอินเทอร์เฟซ LLM และตัวแปรสภาพแวดล้อมของเครื่องมือตรวจสอบเชิงรูปแบบ JasperGold:

# ที่มา: README.md  
export OPENAI_API_KEY=...  
# หรือ: export ANTHROPIC_API_KEY=...  
export PATH=/path/to/jasper/bin:$PATH  
export LM_LICENSE_FILE=<your_jasper_license_server>  
export CDS_LIC_FILE=<your_jasper_license_server>  

รันคำสั่งต่อไปนี้ในไดเรกทอรีรากของ repository เพื่อเริ่มกระบวนการหลัก:

# ที่มา: README.md  
cd FVRuleLearner  
python3 src/main.py  

พารามิเตอร์หลักทั้งหมดจะรวมอยู่ในไฟล์ src/config.py ขั้นตอนการฝึกอบรมต้องกำหนดค่าดังนี้:

# ที่มา: src/config.py  
# เลือกขั้นตอนการดำเนินการ: train / inference / eval  
# global_task = 'inference'  
global_task = 'train'  
# global_task = 'eval'  

# ภารกิจที่เผยแพร่ที่รองรับ:  
# task = "nl2sva_human"  
# task = "nl2sva_machine"  
task = "nl2sva_opencore"  

LLM_gateaway = "openai"  
# LLM_gateaway = "claude"  

llm_model = 'gpt-4o'  
# llm_model = "claude-sonnet-4-5-20250929"  

เมื่อการฝึกอบรมเสร็จสิ้น ผลลัพธ์จะถูกจัดเก็บในโครงสร้างไดเรกทอรีต่อไปนี้:

# ที่มา: README.md  
src/logs/train_<timestamp>_<hostname>_<user>/  
suggestions.pkl  
qtrees.pkl  
qtrees.json  
log.txt  
FLAGS.klepto  

เมื่อต้องการทำการอนุมาน เพียงเปลี่ยน global_task เป็น "inference" และชี้ load_suggestions_path ไปยังไดเรกทอรีบันทึกที่สร้างจากการฝึกอบรมครั้งก่อน นอกจากนี้ ยังสามารถตั้งค่าตัวแปรสภาพแวดล้อม FVRULELEARNER_TRAIN_LOGDIR เพื่อแทนที่เส้นทางบันทึกเริ่มต้น สำหรับข้อมูลเกี่ยวกับความสัมพันธ์ของชุดข้อมูล การกำหนดค่าพารามิเตอร์ที่แนะนำ และวิธีการใช้งานแบบประเมินเท่านั้น (eval-only) โปรดดูเอกสาร README ฉบับเต็มของ repository: https://github.com/NVlabs/FVRuleLearner/blob/main/README.md

สอง. ความท้าทายหลัก: การสร้าง SVA ไม่ใช่แค่การแปลง่ายๆ แต่เป็นการจัดตำแหน่งความหมายที่ตรวจสอบได้

2.1 ช่องว่างทางความหมายระหว่างภาษาธรรมชาติกับ assertion เชิงรูปแบบ

เมื่อมองเผินๆ ภารกิจ NL2SVA ดูเหมือนจะเป็นการแปลงคำอธิบายภาษาธรรมชาติเป็นโค้ด SVA เช่น “เมื่อการเขียนมีผลและ FIFO ไม่เต็ม ตัวชี้เขียนควรได้รับการอัปเดต” อย่างไรก็ตาม ในบริบทที่เข้มงวดของการตรวจสอบเชิงรูปแบบ ประโยคนี้ซ่อนข้อจำกัดทางวิศวกรรมหลายชุดไว้เบื้องหลัง:

  • assertion ควรสุ่มตัวอย่างตามขอบนาฬิกาใด
  • จำเป็นต้องปิดการใช้งาน assertion นี้ระหว่างการรีเซ็ตหรือไม่
  • ควรใช้ตัวดำเนินการ |-> หรือ |=> ระหว่าง antecedent และ consequent หรือไม่
  • จำเป็นต้องแนะนำการดำเนินการเชิงเวลา เช่น $stable, $past หรือ ##[n:m] หรือไม่
  • สัญญาณที่เกี่ยวข้องมาจากชั้นนามธรรมของ testbench หรือจากโค้ด RTL ดั้งเดิม
  • จะตัดสินความเท่าเทียมกันระหว่าง assertion อ้างอิงได้อย่างไร ไม่ใช่แค่ความคล้ายคลึงกันในระดับสตริง

บทความวิชาการของ FVRuleLearner มีชื่อว่า “Operator-Level Reasoning Tree (OP-Tree)-Based Rules Learning for Formal Verification” [1] ไฟล์ README ของ repository ระบุอย่างชัดเจนว่ามันคือไปป์ไลน์การเรียนรู้กฎที่ออกแบบมาสำหรับ NL2SVA โดยเฉพาะ และใช้ JasperGold ในการประเมินไวยากรณ์และฟังก์ชันอย่างครอบคลุม กล่าวคือ โครงการนี้ไม่พอใจแค่กับการ “สร้างโค้ดที่ดูเหมือน SVA” แต่เป้าหมายที่แท้จริงคือการเรียนรู้ “ว่าทำไม assertion หนึ่งถึงผิด และเมื่อพบรูปแบบตัวดำเนินการที่คล้ายกันอีกครั้ง ควรแก้ไขอย่างไร”

2.2 ภารกิจสามประเภทและจุดเริ่มต้นข้อมูล

ในไฟล์กำหนดค่า ภารกิจที่เผยแพร่จะถูกจำกัดอย่างเข้มงวดเป็นสามประเภทต่อไปนี้:

# ที่มา: src/config.py  
if task == "nl2sva_human":  
dataset_path = os.path.join(ROOT, "FVEval", "data_nl2sva", "data", "nl2sva_human.csv")  
elif task == "nl2sva_machine":  
dataset_path = os.path.join(ROOT, "FVEval", "data_nl2sva", "data", "nl2sva_machine_updated.csv")  
elif task == "nl2sva_opencore":  
dataset_path = os.path.join(ROOT, "FVEval", "data_1k", "module_sva_nl_manual_editing.csv")  
else:  
raise ValueError(f"Unsupported release task: {task}")  

需要注意的是,该项目并非面向任意 Verilog 仓库的通用断言生成器,而是围绕特定基准测试格式组织起来的研究原型每条数据记录通常包含自然语言提示、参考断言、设计名称、任务标识符、测试平台及相关上下文信息。

  • Python 主控部分负责组织样本、调用 LLM 生成 SVA 并保存结果;
  • FVEval 组件则负责将生成的结果与参考答案一同放入 JasperGold 可执行的评估框架中,进行闭环验证。

三. สถาปัตยกรรมโดยรวม: การฝึกอบรมตกตะกอนกฎ การอนุมานค้นหากฎ การประเมินปิดลูป

3.1 จุดเริ่มต้นหลักคือเครื่องสถานะ

3.1 ไปป์ไลน์สามขั้นตอน: การฝึกอบรม การอนุมาน และการประเมิน

โค้ดของ src/main.py แม้จะสั้น แต่ได้กำหนดกระบวนการหลักสามขั้นตอนของโครงการอย่างชัดเจน: train (การฝึกอบรม), inference (การอนุมาน) และ eval (การประเมิน)

# ที่มา: src/main.py  
def main():  
if FLAGS.global_task in ['inference', 'train']:  

if FLAGS.model == 'agent':  
start_time = time.time()  
from fv_harwareagent_example import FVProcessor  
processor = FVProcessor()  
processor.main_fv()  
saver.save_stats('overall_runtime', time.time()-start_time)  

elif FLAGS.model == 'timing_agent':  
from hardware_agent.examples.timing_summary_hardwareagent_example import main  
main()  
else:  
raise NotImplementedError()  

if FLAGS.global_task == 'inference':  
from eval import eval  
eval(Path(saver.logdir))  

elif FLAGS.global_task == "eval":  
from eval import eval  
eval(FLAGS.folder_to_eval)  

ตรรกะสำคัญมีดังนี้:

  • การฝึกอบรมและการอนุมาน: ทั้งสองดำเนินการผ่านโมดูล FVProcessor ข้อแตกต่างเพียงอย่างเดียวคือหลังจากงานอนุมานเสร็จสิ้น จะเริ่มกระบวนการประเมินโดยอัตโนมัติ
  • ประเมินเท่านั้น: หากระบุ global_task เป็น "eval" ระบบจะประเมินประสิทธิภาพอีกครั้งโดยตรงกับไดเรกทอรีผลลัพธ์การอนุมานที่มีอยู่

การออกแบบนี้ก่อให้เกิดไปป์ไลน์สามขั้นตอนที่ชัดเจน:

# ที่มา: ย่อจาก src/main.py และ README  
train:  
ตัวอย่างชุดข้อมูล -> LLM สร้าง SVA -> เปรียบเทียบกับ assertion อ้างอิง -> Q-Tree สอบถามข้อผิดพลาด -> บันทึก suggestions.pkl/qtrees.json  

inference:  
prompt ใหม่ -> ค้นหาตัวอย่าง/suggestions/qtrees ที่คล้ายกัน -> LLM สร้างหรือแก้ไข SVA -> JasperGold แก้ไขไวยากรณ์ -> บันทึกผลลัพธ์  

eval:  
ไดเรกทอรีผลลัพธ์ LLM -> ประเมินความคล้ายคลึงข้อความ + ประเมินฟังก์ชัน JasperGold -> สรุปเป็น CSV  

3.2 การกำหนดค่า: ไม่ใช่แค่สิ่งประกอบ แต่เป็น “โปรโตคอล” ของการทดลอง

ในไฟล์ src/config.py การกำหนดค่าสำหรับขั้นตอนการฝึกอบรมและการอนุมานถูกแยกออกจากกันอย่างชัดเจน ขั้นตอนการฝึกอบรมจะปิดการทำงาน RAG (Retrieval-Augmented Generation) และการประเมินหลักของ JasperGold โดยเน้นที่การสร้าง suggestion และสร้าง Q-Tree:

# ที่มา: src/config.py  
if global_task == 'train' and 'nl2sva' in task:  
# Training builds suggestions / Q-Trees; retrieval is disabled here.  
use_RAG = False  
use_JG = False  
RAG_content = ['Suggestions']  
# Number of self-improvement iterations per training sample.  
num_iter = 25  

train_temp_setting = "random"  
if train_temp_setting == "random":  
change_only_bleu_same = True  
low_temp = 0  
high_temp = 1.0  

use_QTree = True  
if use_QTree:  
# Number of questions expanded per Q-Tree level.  
question_tree_width = 3  

PEC_method = 'JasperGold'

ในระหว่างการอนุมาน ระบบจะเปิดใช้งานโมดูล RAG และเปิดใช้กลไก Q-Tree enhanced retrieval:

# ที่มา: src/config.py  
elif global_task == 'inference' and 'nl2sva' in task:  
use_RAG = True  
similarity_str = ["Question"]  
eval_content = ["similarity","jg"]  

if use_RAG:  
RAG_content = ['Examples', 'Suggestions']  

if 'Examples' in RAG_content:  
prompting_instruction = 0  
Examples_top_k = 1  

if 'Suggestions' in RAG_content:  
Suggestions_top_k = 3  
Suggestions_Reasoning = False  

# Enable FVRuleLearner's Q-Tree-enhanced retrieval.  
retrieval_on_ranking = True  
if retrieval_on_ranking:  
qtree_similarity_top_k = 5  
qtree_ranking_mode = 'prompt'  
rule_source = 'generate'  

llm_score_weight = 0.5  
operator_score_weight = 0.5  
operator_pruning_threshold = 0.0  

deduplication = True  
operator_explanation = False  
filter_functionality = True  
retrieve_str = ["Suggestions"]  
load_suggestions_path = DEFAULT_TRAIN_LOGDIR  

แผนการกำหนดค่านี้ควรค่าแก่การอภิปรายในเชิงลึก โดยแยกความแตกต่างระหว่าง “การค้นหาตัวอย่าง” และ “การค้นหากฎ” อย่างชัดเจน

  • Examples เป็นกลไกการเรียนรู้ในบริบท (in-context learning) แบบคลาสสิก
  • Suggestions คือความรู้กฎที่กลั่นกรองจากกระบวนการแก้ไขข้อผิดพลาดในประวัติศาสตร์

เห็นได้ชัดว่าสิ่งหลังคือแกนหลักทางเทคนิคที่แท้จริงของ FVRuleLearner

สี่. Q-Tree: แยกข้อผิดพลาดครั้งเดียวเป็นเส้นทางการอนุมานที่เรียนรู้ได้

4.1 ทำไมต้องเป็นโครงสร้างต้นไม้ ไม่ใช่แค่ข้อความสะท้อน

ระบบซ่อมแซมตัวเองของ LLM ส่วนใหญ่เมื่อพบกับความล้มเหลว จะถามเพียงว่า: “โปรดอธิบายข้อผิดพลาดและให้คำแนะนำ” ในขณะที่ FVRuleLearner เลือกเส้นทางที่มีโครงสร้างมากกว่า: Q-Tree โดยแยกความแตกต่างระหว่าง assertion ที่สร้างขึ้นกับ assertion อ้างอิง ออกเป็นคำถามหลายระดับ:

  • ความรู้พื้นฐาน: ครอบคลุมคำอธิบายภาษาธรรมชาติ, testbench, assertion ที่สร้างขึ้น, assertion อ้างอิง และความรู้ทั่วไปเกี่ยวกับไวยากรณ์ SVA
  • คำถามเชิงสำรวจ: ตั้งคำถามจากหลายมิติ เช่น ตัวดำเนินการ (operator), จังหวะเวลา (timing), การเปรียบเทียบ (comparison)
  • คำถามวิเคราะห์เฉพาะ: สอบถามเชิงลึกสำหรับแต่ละจุดที่แตกต่าง
  • การสร้างกฎ: บีบอัดผลการวิเคราะห์เป็นกฎที่สามารถนำกลับมาใช้ใหม่ได้

โครงสร้างข้อมูลหลักถูกกำหนดไว้ใน src/qtree_builder.py:

# ที่มา: src/qtree_builder.py  
class QuestionLevel(Enum):  
"""Levels in the Q-Tree hierarchy"""  
BACKGROUND = "background"  
EXPLORATORY = "exploratory"  
SPECIFIC_ANALYSIS = "specific_analysis"  
RULE_GENERATION = "rule_generation"  


@dataclass  
class QuestionNode:  
"""Node in the Q-Tree structure"""  
id: str  
question: str  
level: QuestionLevel  
parent_id: Optional[str] = None  
children: List[str] = field(default_factory=list)  
answer: Optional[str] = None  
rules_generated: List[str] = field(default_factory=list)  
metrics: Dict[str, Any] = field(default_factory=dict)  


class QTreeBuilder:  
"""Builds Q-Tree for assertion analysis and rule generation"""  

def __init__(self, agents: Dict[str, Any], config_flags=None):  
self.agents = agents  
self.nodes: Dict[str, QuestionNode] = {}  
self.tree_results = []  
self.max_questions_per_level = getattr(config_flags, 'question_tree_width', 3) if config_flags else 3  
self._last_diversity_metrics = None  
self._row_data = None  
self.qa_time = 0.0  

สามารถเปรียบเทียบได้กับกระบวนการตรวจสอบโค้ดของผู้เชี่ยวชาญด้านการตรวจสอบเชิงรูปแบบ: ผู้เชี่ยวชาญจะไม่เพียงแค่พูดว่า “ผิด” แต่จะถามว่า “การนัยเชิงเวลาถูกต้องหรือไม่?” “ตัวดำเนินการเปรียบเทียบตรงกับตรรกะสี่สถานะหรือไม่?” “ควรวางเงื่อนไขไว้ใน antecedent หรือ consequent?” — คำถามเหล่านี้ก่อตัวเป็นโครงสร้างต้นไม้ และในที่สุดจะตกตะกอนเป็นกฎที่สามารถนำกลับมาใช้ใหม่ได้

4.2 กระบวนการสร้าง Q-Tree

# ที่มา: src/qtree_builder.py  
def build_qtree_for_assertion_pair(self,  
generated_assertion: str,  
reference_assertion: str,  
row: Any,  
metrics: Dict[str, Any]) -> List[QuestionNode]:  
"""  
Build a Q-Tree to analyze differences between generated and reference assertions  

Tree Structure:  
Root: Background Knowledge (context about the problem)  
Level 1: Exploratory questions about major differences  
Level 2: Specific analysis questions for each difference  
Level 3: Rule generation based on the analysis  
"""  
tree_nodes = []  
node_counter = 0  
self._row_data = row  

background_knowledge = self._get_background_knowledge(row, generated_assertion, reference_assertion)  

exploratory_questions = self._generate_exploratory_questions(  
generated_assertion, reference_assertion, metrics, row  
)  

for question in exploratory_questions:  
node = QuestionNode(  
id=f"explore_{node_counter}",  
question=question,  
level=QuestionLevel.EXPLORATORY,  
parent_id=None,  
metrics=metrics  
)  
node.answer = self._answer_exploratory_question(  
question, generated_assertion, reference_assertion, row  
)  

# Level 2: Generate specific analysis questions  
for parent_node in exploratory_nodes:  
specific_questions = self._generate_specific_analysis_questions(  
parent_node, generated_assertion, reference_assertion  
)  

# Level 3: Generate rules based on analysis  
for parent_node in specific_nodes:  
rules = self._generate_rules_from_analysis(  
parent_node, generated_assertion, reference_assertion  
)  

แนวคิดการออกแบบของโค้ดนี้ชัดเจนมาก: Q-Tree ไม่ได้ถูกใช้โดยตรงสำหรับ “การแก้ไขโค้ด” แต่ก่อนอื่นจะจัดโครงสร้างพื้นที่ข้อผิดพลาดอย่างเป็นระบบ สำหรับภาษา SVA ซึ่งพึ่งพาความหมายของตัวดำเนินการอย่างมาก กลไกการสอบถามเชิงโครงสร้างมีความเสถียรและเชื่อถือได้มากกว่าการสะท้อนครั้งเดียว ตัวอย่างเช่น:

  • |-> และ |=> แสดงถึงความสัมพันธ์ “การนัย” แบบเดียวกันหรือไม่? คำตอบคือไม่ — อันแรกคือการนัยที่ทับซ้อนกันภายในรอบเดียวกัน ส่วนอันหลังคือการนัยที่ไม่ทับซ้อนซึ่งจะเริ่มในรอบถัดไป
  • == และ === เป็นเพียงความแตกต่างของรูปแบบการเขียนโค้ดหรือไม่? ไม่ใช่ อย่างหลังทำการเปรียบเทียบสี่สถานะ (case equality)
  • && และ || สามารถเลือกได้โดยสัญชาตญาณทางภาษาเท่านั้นหรือไม่? ไม่ได้ การเลือกนี้กำหนดโดยตรงว่าขอบเขตของเงื่อนไข antecedent กว้างหรือแคบเกินไป

คุณค่าหลักของ Q-Tree คือการแปลงความแตกต่างข้างต้นเป็น “โหนดคำถามที่อธิบายได้” จากนั้นบีบอัดโหนดเหล่านี้เป็นกฎ (rule) ที่สามารถค้นหาได้ในภายหลัง

ห้า. RAG และการค้นหาเสริม: ไม่ใช่การหาคำตอบที่คล้ายกัน แต่เป็นการหาประสบการณ์การแก้ไขข้อผิดพลาดที่คล้ายกัน

5.1 RAGAgent จัดระเบียบเอกสารอย่างไร

RAGAgent ใน FVRuleLearner รองรับโหมดการค้นหาสองประเภท: Examples และ Suggestions โหมด Examples มีเป้าหมายเพื่อค้นหาตัวอย่างคำถามและคำตอบที่คล้ายกัน ในขณะที่โหมด Suggestions ใช้สำหรับค้นหากฎในประวัติศาสตร์ ในระหว่างการเริ่มต้น ระบบจะเลือกโมเดล embedding โดยอัตโนมัติ โดยการกำหนดค่าเริ่มต้นคือ all-MiniLM-L6-v2

# ที่มา: src/rag_agent.py
class RAGAgent:
def __init__(self, documents, rag_type, embedding_model='sbert'):
self.delimiter = "<---->"
self.rag_type = rag_type
self.qtree_engine = None

if rag_type == "Suggestions":
if FLAGS.filter_functionality:
documents = [doc for doc in documents if self.check_functionality(doc)]
print(f"@@@DEBUG: Length of the filtered documents is @@@ {len(documents)} @@@")

self.original_documents = [doc.replace(self.delimiter, "n").strip() for doc in documents]
self.documents = [self.extract_section(doc, FLAGS.similarity_str, full_string=True) for doc in documents]

if rag_type == "Suggestions":
self.retrieve_documents = [self.extract_section(doc, FLAGS.retrieve_str, full_string=True) for doc in documents]
elif rag_type == "Examples":
self.retrieve_documents = [self.extract_section(doc, ["all"], full_string=True) for doc in documents]

self.model = self._load_model(embedding_model)
self


⚠️ หมายเหตุ: เนื้อหาได้รับการแปลโดย AI และตรวจสอบโดยมนุษย์ หากมีข้อผิดพลาดโปรดแจ้ง

☕ สนับสนุนค่ากาแฟทีมงาน

หากคุณชอบบทความนี้ สามารถสนับสนุนเราได้ผ่าน PromptPay

PromptPay QR
SCAN TO PAY WITH ANY BANK

本文来自网络搜集,不代表คลื่นสร้างอนาคต立场,如有侵权,联系删除。转载请注明出处:https://www.itsolotime.com/th/archives/33488

Like (0)
Previous 2026年5月6日 pm10:48
Next 6 days ago

相关推荐