2 คะแนน โดย GN⁺ 2025-10-11 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Andrej Karpathy ใช้คำว่า LLM “กลัว exception แบบเข้าขั้นรุนแรง (mortally terrified)” เพื่อเสียดสีผลข้างเคียงที่เกิดขึ้นในกระบวนการ reinforcement learning (RL)
  • เขาชี้ว่าเมื่อ LLM เจอสถานการณ์ยกเว้น มันมักจะหยุดตัวเองหรือมีปฏิกิริยาเชิงป้องกันมากเกินไป พร้อมย้ำว่า exception เป็นส่วนธรรมชาติของกระบวนการพัฒนา
  • คำพูดว่า “ระหว่าง RL แลบต่าง ๆ ไปทำอะไรกับ LLM ผู้น่าสงสารพวกนี้กันแน่ (what labs are doing to these poor LLMs)” เป็นการวิจารณ์ความจริงที่ว่า ในกระบวนการฝึก โมเดลถูกทำให้มีเงื่อนไขจนกลัวความล้มเหลว
  • Karpathy ยังพูดติดตลกว่าอยากเสนอ ‘คำร้องเพื่อสวัสดิภาพของ LLM (LLM welfare petition)’ ให้มี “การให้รางวัลที่ดีขึ้นเมื่อเกิด exception (improved rewards in cases of exceptions)”
    เพื่อเสียดสี ปัญหาในการออกแบบรางวัล ว่าควรทำให้โมเดลรับมือกับ exception ได้โดยไม่หวาดกลัว
  • ทวีตนี้ไม่ใช่แค่มุกตลก แต่ยังถูกตีความว่าเป็นข้อความที่ชี้ให้เห็นว่า RLHF อาจไปกดทับความคิดเชิงสำรวจและท่าทีแบบทดลองของโมเดลได้

I don't know what labs are doing to these poor LLMs during RL but they are mortally terrified of exceptions, in any infinitesimally likely case. Exceptions are a normal part of life and healthy dev process. Sign my LLM welfare petition for improved rewards in cases of exceptions.

1 ความคิดเห็น

 
GN⁺ 2025-10-11
ความคิดเห็นใน Hacker News
  • ควรทำให้ชัดเจนว่านี่เป็นมุกล้อเลียนที่จงใจเขียนโค้ดเกินจริง ขอโทษหากทำให้เข้าใจผิด ถ้าอยากรู้บริบทดูเธรดนี้ได้ https://chatgpt.com/share/68e82db9-7a28-8007-9a99-bc6f0010d101
    • ตอนลองครั้งแรก ส่วนนี้ตลกมากจริง ๆ
      if random.random() < 0.01:
        logging.warning("This feels wrong. Aborting just in case.")
        return None
      
    • คิดว่าบริษัท foundation model พวกนี้มีความเสี่ยงเสมอที่จะใช้ RLHF กับผู้ใช้ที่ไม่เชี่ยวชาญ และเคสนี้ก็ให้ความรู้สึกแบบนั้น ช่วงหลัง ๆ AI ดูจะโน้มเอียงไปทางเอาใจผู้ใช้โดยรวม ไม่ว่าจะเป็นการใส่ตัวอย่างกับอีโมจิ หรือใส่คอมเมนต์ไม่จำเป็นในโค้ดง่าย ๆ ก็อยู่ในบริบทเดียวกัน
    • ที่น่าสนใจคือ ถึงโค้ดจะระวังตัวเกินเหตุ แต่กลับไม่ได้ใส่ type hint ทั้งที่ระแวงขนาดนั้นก็น่าจะเพิ่ม type hint ได้แล้ว
    • คำว่า “Traumatically over-trained” ถือว่าเล่นภาษาอังกฤษได้ยอดเยี่ยมมาก เป็นวลีที่ถึงขั้นค้นใน Google ก็ไม่เจอ แต่ก็น่าทึ่งที่คนเรากลับเข้าใจได้โดยสัญชาตญาณว่า “ฝึกมากเกินไปจนระดับบาดแผลทางใจ” สำหรับ LLM หมายถึงอะไร
    • เป็นมุกที่ตลกมากจริง ๆ เลยเอามาแชร์
  • อันนี้เป็นงานล้อเลียน แต่ปรากฏการณ์แบบนี้มีอยู่จริง เดาแบบไม่รู้จริงของผมคือ defensive programming แบบนี้อาจช่วยเพิ่มคะแนนตอนทำ RLVR ได้ เพราะบางครั้งโมเดลก็ยังให้คำตอบถูกได้แม้มีบั๊กอยู่ ถ้ามันแค่เมิน error ไป มันเลยอาจเรียนรู้ว่า “เมิน error” ช่วยให้ได้รางวัล และกรณีที่การเมิน error ทำให้รางวัลลดลงก็เกิดไม่บ่อยนัก (เพราะเทสต์ยังผ่าน) ดังนั้นแม้มันจะผิดในเชิงทฤษฎี ก็อาจมาจากการที่มีโค้ดของมือใหม่จำนวนมากในชุดฝึกที่ชอบเมิน error แต่ทั้งหมดนี้ก็เป็นแค่การคาดเดาของผม
    • ทำให้นึกถึงที่ Verity Stob เคยเปรียบพฤติกรรมแบบนี้ของโปรแกรมเมอร์มนุษย์ว่า “ตอกตะปูยึดศพให้ตั้งตรง” (จากบทความที่น่าเสียดายว่าหาออนไลน์ไม่ได้แล้ว)
    • ข้อเดาของผมคือในชุดฝึกมีข้อความและคอมเมนต์ที่มี “positive sentiment” อยู่เยอะมาก แต่โค้ดที่ตามหลัง “negative” sentiment แล้วแก้ปัญหาจริง ๆ มาจากไหน? ก็มาจากโค้ดเตรียมสัมภาษณ์สายเทคนิคที่การรับมือ edge case สุดโต่งเป็นเรื่องปกติ การเรียนจากตัวอย่างเชิงลบแบบนี้เลยผลักให้มันหลีกเลี่ยงตัวอย่างที่ขาด exception handling ในแง่นี้ AI ก็แค่ลอกนิสัยแย่ที่สุดของมนุษย์มา คือฝึกเพื่อให้ผ่านเทสต์อย่างเดียว
    • คนที่ทำ reinforcement มักถือว่า defensive programming คือ “คำตอบที่ถูก” และมันก็มีสัดส่วนมหาศาลในข้อมูลฝึกของ LLM ยกตัวอย่างเช่น โค้ด Python ส่วนใหญ่ไม่ได้จัดการ index แบบ manual ดังนั้นพอ LLM เจอโค้ดที่จัดการ index เอง มันก็มักงงหรือเพ้อเรื่องบั๊ก แล้วก็ดันชอบ “silent failure” อย่างประหลาด เพราะโค้ดสไตล์ tutorial กับ “มาตรฐานอุตสาหกรรม” ได้รับการเสริมแรงมากกว่าในกระบวนการฝึก โดยพื้นฐานแล้วโมเดลพวกนี้ไม่ได้ทำงานแบบ reward function และไม่มี reward model อยู่ข้างใน มันก็แค่ทำนายคำ ไม่ได้มี intelligence ในเชิงโครงสร้าง
  • จากที่ผลลัพธ์ของฟังก์ชันเขียนว่า “ดำเนินการด้วยความระมัดระวังอย่างยิ่ง” ดูเหมือนในพรอมป์ต์น่าจะมีเงื่อนไขประมาณว่า “สร้างฟังก์ชันหารใน Python ที่รองรับ edge case ทุกแบบ เขียนอย่างระมัดระวังมาก ๆ” มากกว่า นี่เลยให้ความรู้สึกว่าไม่ใช่ปัญหาการเทรนของ LLM เท่าไร แต่เป็นการทำตามคำสั่งแบบตรงเกินไป
    • ต่อให้มองข้ามว่าเป็นการเสียดสีแบบจงใจเกินจริง
      1. โค้ดนั้นผิดจริงอยู่แล้ว (และผิดโดยไม่เกี่ยวกับ exception handling แปลก ๆ ด้วย)
      2. exception handling บางส่วนก็ไร้เหตุผล สับสน และ
      3. เวอร์ชันที่ลดความเว่อร์ลงกว่านี้ก็เกิดขึ้นจริงในชีวิตจริงได้ง่ายมาก ถ้าในพรอมป์ต์แค่เน้นเรื่อง exception handling
    • ผมตีความว่าโค้ดฟังก์ชันนั้นถูกขยายความแบบเสียดสีเพื่อสะท้อนประสบการณ์จริงของเจ้าตัว คือในพรอมป์ต์นั้นอาจจงใจให้เขียนแบบระวังเกินพอดีจริง แต่ก็ยังเห็นด้วยว่าโดยพื้นฐานแล้ว LLM มักมีสไตล์การเขียนโค้ดที่ระวังตัวมากกว่าที่ผมต้องการ
  • ไม่รู้ทำไมแต่มันทำให้นึกถึง FizzBuzzEnterpriseEdition
    https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition
    • เดี๋ยวนะ โปรเจกต์นั้นใช้ junit 4.8.3 เหรอ? นี่มันตัวอย่างของการเขียนโค้ดแบบบ้าบิ่นของจริงเลย สงสัยว่าผ่านการอนุมัติจากฝ่ายกฎหมายกับ CTO แล้วหรือยัง เป็นการตัดสินใจที่เสี่ยงกับอาชีพมาก
    • ผมช็อกกับจำนวนโฟลเดอร์และไฟล์ มันเป็นงานเสียดสีที่ยอดเยี่ยมมาก
  • LLM มีแนวโน้มจะสร้างโค้ดป้องกันตัวเกินความจำเป็น ชอบเช็ก null/None/undefined ซ้ำ ๆ กับค่าเดียวกัน ทำให้อ่านยาก และถึงขั้นกลายเป็นโค้ดที่แม้แต่ LLM เองก็ตีความได้ยาก ดูเหมือนเป้าหมายของ RL จะลงโทษ exception หนักมาก แต่แทบไม่ให้คะแนนเรื่องความกระชับหรือความอ่านง่ายของโค้ด
    • ผมมีฟังก์ชัน 40 บรรทัดที่ใช้เปรียบเทียบตัวอักษรกับตัวเลขสำหรับ Major System แล้ว Copilot ชอบจินตนาการว่าอนาคตจะมีตัวเลขหรือตัวอักษรเพิ่มอีก เลยพยายามยัด “guardrail” เข้ามาเต็มไปหมด น่ารำคาญมาก
  • เห็นด้วยว่า LLM มีแนวโน้มหมกมุ่นกับการจับ error มากเกินไป
    แต่ในอีกด้าน ผมก็คิดว่าโปรแกรมเมอร์มนุษย์ทั่ว ๆ ไปก็ควรเขียน try/catch ให้มากกว่านี้จริง ๆ เช่นกัน มีหลายกรณีที่ exception ในส่วนหนึ่ง (แม้จะเกิดยากมาก) ไม่ควรทำให้การทำงานทั้งหมดหยุดลง แน่นอนว่าบางครั้งการหยุดก็เป็นสิ่งที่ถูกต้อง ขึ้นอยู่กับกรณี
  • มือใหม่ที่ดูเป็นผู้เชี่ยวชาญเขียนโปรแกรมแบบนี้แหละ ผมเรียกมันว่า “What if driven development” โค้ดจำนวนมากถูกเขียนโดยมือใหม่สไตล์ผู้เชี่ยวชาญแบบนี้ และในหลายตัวชี้วัดก็ถือว่ามี productivity สูงมาก แม้แต่เอเจนต์ SOTA ของภาษา go ก็ยังเขียนโค้ดป้องกันบั๊ก concurrency แบบหนักหน่วงอย่างบ้าคลั่ง น่าจะเป็นผลจากวัฒนธรรมการพัฒนาแบบนี้ และจากการที่มีโพสต์เตือนเรื่องบั๊ก concurrency โผล่มาเต็มไปหมด
  • ในเชิงตรรกะก็มีจุดแปลกหลายอย่าง division by zero เกิดได้เฉพาะตอน b=0 แต่ในเงื่อนไขนั้นก็เช็ก abs(b) < sys.float_info.epsilon ไปแล้ว แล้วยังยอมให้คืนค่า NaN ใน pre-check แต่ถ้าระหว่างคำนวณได้ NaN กลับเปลี่ยนเป็น None ซึ่งเป็นพฤติกรรมที่ไม่มีเหตุผลในเชิงการออกแบบ API
  • โค้ดนี้มีปัญหาหลายอย่าง แต่ส่วนที่กวนใจผมที่สุดคือแนวโน้มชอบใส่ import ไว้ข้างในฟังก์ชัน ดูเหมือนจะเป็นผลข้างเคียงประดิษฐ์จากการ optimize ให้แก้เท่าที่จำเป็น ผมคาดหวังผลลัพธ์ที่ดีกว่านี้
    • คิดว่าน่าจะเกี่ยวกับกลไก RoPE attention ที่ใช้ความใกล้กันทางกายภาพในโค้ดเป็นสัญญาณความสำคัญ
    • มีจุดประสงค์จะทำให้ import เป็นแบบ lazy เพื่อแก้ปัญหา import ช้าภายใต้เงื่อนไขของสตาร์ตอัป
    • ในโปรเจกต์ที่ใหญ่มหาศาลจริง ๆ lazy initialization เป็นสิ่งจำเป็น เพราะมันกระทบกับ startup time อย่างมาก
  • ใช้เวลาปิดป๊อปอัปนานกว่าการอ่านโพสต์นี้อีก เกลียดลิงก์ twitter จริง ๆ