1 คะแนน โดย GN⁺ 2024-04-19 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

Effort คืออะไร?

  • Effort หมายถึงพลังงาน เวลา และทรัพยากรที่投入เพื่อทำบางสิ่งให้สำเร็จหรือบรรลุเป้าหมาย
  • หมายถึงความพยายามและความอุตสาหะที่จำเป็นต่อการเอาชนะอุปสรรคหรือให้ได้ผลลัพธ์ตามต้องการ
  • Effort อาจเป็นได้ทั้งทางกายและทางใจ
    • ความพยายามทางกาย เช่น พลังงานที่ใช้ในการยกของหนักหรือวิ่งมาราธอน
    • ความพยายามทางใจ เช่น สมาธิและพลังใจที่จำเป็นในการแก้ปัญหาที่ซับซ้อนหรือเรียนรู้ทักษะใหม่
  • เป็นองค์ประกอบสำคัญในการประสบความสำเร็จในหลายด้านของชีวิต เช่น การเติบโตส่วนบุคคล การทำงาน และการศึกษา

ความเห็นของ GN⁺

  • Effort ไม่ได้หมายถึงเพียงปริมาณเวลา หรือพลังงานที่ทุ่มลงไปเท่านั้น แต่เป็นแนวคิดที่เกิดจากหลายปัจจัยร่วมกัน เช่น ความต่อเนื่อง สมาธิ และแรงจูงใจ ดังนั้น ต่อให้พยายามอย่างหนัก ก็ไม่ได้หมายความว่าจะประสบความสำเร็จเสมอไป
  • โดยเฉพาะงานที่ต้องใช้ Effort ทางใจ ควรระวังไม่ให้เกิดภาวะหมดไฟ การหาวิธีรักษาระดับ Effort ให้ต่อเนื่องด้วยการพักผ่อนและให้รางวัลที่เหมาะสมจึงเป็นเรื่องสำคัญ
  • แต่ละคนอาจมีวิธีลง Effort ที่ต่างกัน บางคนเหมาะกับการทุ่มเทอย่างเข้มข้นในระยะสั้น ขณะที่บางคนเหมาะกับการค่อย ๆ ลง Effort อย่างสม่ำเสมอในระยะยาว การหาวิธีที่เหมาะกับตัวเองจะมีประสิทธิภาพมากกว่า

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

 
GN⁺ 2024-04-19
ความคิดเห็นบน Hacker News
  • แก่นของอัลกอริทึมดูเหมือนจะเป็นการตัดแต่งพารามิเตอร์ระหว่างรัน แล้วกำหนด น้ำหนักที่สำคัญน้อยกว่า จากลำดับค่าสัมบูรณ์ของน้ำหนักที่จะถูกตัดแต่งภายในแต่ละกลุ่ม ทำให้เป็น 0 เพื่อทำให้ เมทริกซ์น้ำหนักมีความเบาบาง
    ถ้าค้นหาเรื่องการตัดแต่งโมเดลจะเจอผลลัพธ์จำนวนมาก และ https://arxiv.org/abs/2305.11627 ก็ใช้ “การตัดแต่งตามขนาด” เป็น baseline พร้อมอ้างถึง https://arxiv.org/pdf/2301.00774.pdf
    ไม่ค่อยชอบวิธีที่งานวิจัยบางชิ้นนำ baseline ไป implement แบบลวก ๆ แล้วอวดวิธีของตัวเอง หรือใช้ศัพท์คณิตศาสตร์เยอะ ๆ มาห่อหุ้มเอาไว้ บล็อกโพสต์ต้นทางอธิบายวิธีนี้ให้คนที่แทบไม่มีพื้นความรู้เข้าใจได้ง่ายกว่ามาก

    • เดือนที่ผ่านมาผมใช้ไปกับการทำให้งานวิจัยนี้ ทำซ้ำได้และเชื่อถือได้ ให้มากที่สุด implementation เดิมไม่มีประสิทธิภาพอย่างมาก และแม้หลังจากที่การคูณเมทริกซ์บน Metal/GPU เร็วขึ้นแล้ว ผมก็ยังใช้เวลามากในการปรับส่วนที่เหลือของ implementation ให้ใกล้เคียงกับ Llama.cpp มากที่สุด เพื่อให้ benchmark ได้ง่ายขึ้น
      แนวทางในเปเปอร์ที่กล่าวถึงดูเหมือนจะเป็นแบบ static และดูเหมือนจะไม่ได้เสนออัลกอริทึมที่ทำให้การคำนวณจริงเร็วขึ้นด้วยผลลัพธ์ 20~50% นั่นเป็นส่วนใหญ่ของความยากเลย สักวันหนึ่งผมตั้งใจจะหาเวลาอ่านวรรณกรรมที่เกี่ยวข้องอย่างจริงจัง
      ท้ายที่สุดผมอยากเพิ่ม หน้าอ้างอิง พร้อมกับเปเปอร์ที่คนอื่น ๆ โพสต์ไว้ในคอมเมนต์ คิดว่าอีกไม่นานอาจมีใครสักคนเจอบทความที่สรุปอัลกอริทึมนี้ไว้แล้วก็ได้
      ระหว่างพัฒนาผมถาม gpt-4 และลองกูเกิลแล้ว แต่สิ่งที่พบส่วนใหญ่เป็นแบบ static หรือเป็นแนวตัดมิติ/เลเยอร์ทั้งก้อนออกโดยพลการแล้วฝึกใหม่ ไม่พบอะไรที่ตรงกับไอเดียนี้พอดี
    • “ใช้ศัพท์คณิตศาสตร์เยอะ ๆ เพื่อห่อหุ้มวิธีของตัวเองและ implement baseline แบบแย่ ๆ” ดูเหมือนจะเป็นสัญญาณของ เปเปอร์ที่ไม่ดี
      ยิ่งบทความแน่นและเข้าใจยากเท่าไร ก็ยิ่งมีโอกาสมากขึ้นที่จะซ่อนวิทยาศาสตร์ที่บกพร่องไว้ข้างใน
  • ชอบประโยคนี้ในส่วน implementation บน GPU
    “ผู้อ่านที่เพิ่งเริ่มเขียนโปรแกรม GPU อาจถามตอนนี้ว่า - มันทำงานได้อย่างไร?
    ผู้อ่านที่มีประสบการณ์เขียนโปรแกรม GPU อาจถามว่า - แล้วมันทำงานได้อย่างไรกันแน่?”

    • จากที่เข้าใจ ต้อง implement การอ่านหน่วยความจำและบางอย่างในทางที่ ตรงกันข้าม กับวิธีที่โดยทั่วไปถือว่าเป็นแนวทางที่ถูกต้อง
      คงดีถ้ามีคนที่รู้ Metal จริง ๆ มาช่วยรีวิวโค้ดนี้ นี่เป็นความพยายามเขียนโปรแกรม GPU ครั้งแรกของผม
  • “ลองพลิกเมทริกซ์ จัดเรียงองค์ประกอบตามแถว แล้วมองการคูณจากทิศทางนั้นใหม่ คนฉลาด ๆ เรียกสิ่งนี้ว่า รูปแบบ compressed sparse row (CSR) ตอนนี้ถ้าจะคูณ ก็เอา 1 ของเวกเตอร์มาคูณกับ 256 แล้วบวกเข้าไปที่แถวที่ 3 ของเวกเตอร์ผลลัพธ์ ประมาณนี้ ต่อไปมาดูกันว่าจะเกิดอะไรขึ้นถ้าตัดคอลัมน์สุดท้ายที่มีค่าต่ำสุดออก”
    สงสัยว่ามันเชื่อมโยงกับวิธีที่ CSR ลดจำนวนการคูณอย่างไร

    • ช่วยเรียบเรียงคำถามใหม่ได้ไหม? ผมยังไม่ค่อยเข้าใจ
  • วิธีนี้ดูคล้าย ความเบาบางแบบกึ่งมีโครงสร้าง หรือที่เรียกว่า 2:4 sparsity จึงน่าจะเปรียบเทียบอย่างชัดเจนได้ จากที่อ่านผ่าน ๆ เทคนิคนี้ถูกปรับให้เหมาะกับ Apple Silicon, เร็วขึ้นประมาณ 2 เท่าที่ sparsity 75%, เป็นแบบ dynamic ที่ใช้ระหว่าง runtime ตามอินพุต และสามารถเลือกระดับ sparsity ได้
    ในทางกลับกัน 2:4 semi-structured sparsity ถูกปรับให้เหมาะกับ GPU ที่มี sparse tensor core คือ Nvidia Ampere เป็นต้นไป, เร็วขึ้นประมาณ 2 เท่าที่ sparsity 50%, เป็นแบบ static ที่ใช้กับสถานะที่จัดเก็บของโมเดล และที่ sparsity 50% ก็มีโอกาสให้ผลลัพธ์แย่กว่าเทคนิคนี้
    สิ่งที่อยากเห็นคือการเปรียบเทียบระหว่างผลลัพธ์ของ semi-structured sparsity ที่ sparsity 50% และเร็วขึ้น 2 เท่า กับผลลัพธ์ของเทคนิคนี้ที่ sparsity 75% และเร็วขึ้น 2 เท่า

    • ขอบคุณที่ตรวจสอบให้ ผมเองก็หวังว่าจะมีการทดสอบเพิ่มเติมออกมาเร็ว ๆ
      ที่เลือก Apple Silicon เพราะพัฒนาได้ง่าย อัลกอริทึมนี้อาจทำผลงานได้ดีบนสถาปัตยกรรมอื่นด้วย
  • ในฐานะคนที่เคยใช้ CSR มาก่อน เรื่องนี้ไม่น่าแปลกใจ ในบรรดารูปแบบที่ใหม่กว่า อาจมีแบบที่เข้ากับคุณลักษณะของฮาร์ดแวร์ได้ดีกว่า เช่น block ELL
    รูปแบบแบบนั้นหลีกเลี่ยงการอ่านที่ไม่ถูกรวมกันหรือ gather ได้ แต่โค้ดจะยุ่งยากขึ้น

    • ดีใจที่ในที่สุดก็เจอคนมีประสบการณ์กับ CSR
      bucketMul แทบไม่มีการอ่านที่ไม่ถูกรวมกัน และใช้โครงสร้างข้อมูลที่ต่างจาก CSR ทั่วไป อธิบายไว้ที่นี่: https://kolinko.github.io/effort/bucketmul.html
      แบ่งแต่ละแถวของเมทริกซ์ออกเป็น 16 ส่วน แล้วเลือกว่าจะต้องอ่านส่วนไหน การเขียนเป็นแบบเชิงเส้นทั้งหมด
      แต่ตอนนี้ผมก็ไม่แน่ใจว่าที่พูดอยู่สมเหตุสมผลไหม วันนี้ดึกแล้วและเป็นวันที่ยาวนาน
  • เป็นไอเดียและบทความที่ดี ผมเองก็ทำงานด้าน sparsity ในการอนุมานของโครงข่ายประสาทอยู่เหมือนกัน และนึกถึงบางประเด็นที่ควรรู้ไว้
    เมื่อเทียบกับการทำ การคูณเมทริกซ์-เวกเตอร์ แบบหนาแน่น อัลกอริทึมนี้เพิ่มความซับซ้อนของอัลกอริทึม แต่ลดทราฟฟิกของหน่วยความจำ การคูณเมทริกซ์-เวกเตอร์มักติดคอขวดที่หน่วยความจำ ดังนั้นถ้าลดการเข้าถึงหน่วยความจำได้ throughput ก็จะสูงขึ้น อย่างไรก็ตาม หากขนาด batch มากกว่า 1 การเข้าถึงหน่วยความจำจะไม่ใช่คอขวดอีกต่อไป และมีความเป็นไปได้สูงที่ความเร็วที่เพิ่มขึ้นจะหายไปอย่างรวดเร็ว
    สำหรับตัวเปรียบเทียบ ผมอยากเห็นไม่ใช่แค่โมเดลเดียวกัน แต่รวมถึงโมเดลอื่นที่มีสถาปัตยกรรมเร็วกว่า 2 เท่าด้วย เช่น ถ้าใช้วิธีนี้กับ LLM พารามิเตอร์ 13B ที่ sparsity 50% จะเทียบกับ LLM พารามิเตอร์ 7B เป็นอย่างไร และเทียบกับ LLM เดียวกันที่ quantize ให้เหลือครึ่งหนึ่งของ bitwidth อ้างอิงเป็นอย่างไร ถ้าภายในเวลาเท่ากันสามารถให้เอาต์พุตที่มี fidelity สูงกว่าเฟรมเวิร์กอนุมานเดิมได้ ก็น่าจะเป็นประเด็นสำหรับเปเปอร์ที่น่าสนใจ
    เนื่องจากข้ามการคูณไป ข้อผิดพลาดจากการประมาณน่าจะเอนเอียงไปทางทำให้ค่าสัมบูรณ์เล็กกว่าผลลัพธ์จริงเสมอ ถ้าเพิ่ม เทอมชดเชย เพื่อแก้ systematic error นั้นได้ ประสิทธิภาพน่าจะดีขึ้นอีกเล็กน้อย

    • ความซับซ้อนของอัลกอริทึมไม่ได้เพิ่มขึ้นจริง ๆ การคูณคือ O(effrt * inDim * outDim), การคำนวณ dispatch คือ O(inDim), และการหาจุด cutoff คือ O(~inDim * log inDim)
      สัญกรณ์ Big-O อาจไม่เหมาะกับงานบน GPU มากนัก แต่ในกรณีนี้ก็ประมาณได้ถูกต้อง
      ปัญหาหลักคือข้อจำกัดเชิงสถาปัตยกรรมของ GPU อัลกอริทึมนี้ต้องใช้รีจิสเตอร์/เธรดกรุ๊ป/แคชเมโมรี่มากกว่าวิธีดั้งเดิม และนั่นกลายเป็นคอขวดหลัก อีกทั้งการคูณทั้งหมดใช้ bucket ที่ต่างกัน จึงไม่ง่ายที่จะทำให้งานขนานกันเหมือนโมเดล MoE
      สำหรับสถาปัตยกรรมที่ใหญ่ขึ้น ผมทดสอบค่อนข้างมากกับ Mixtral ซึ่งโดยพื้นฐานแล้วเป็นโมเดล 13B และจากความรู้สึกของผม มันรับมือได้ดีกว่ามาก ความเร็วอนุมานต่อ effort ยังคงอยู่ และคุณภาพต่อ effort ก็ยังให้ผลลัพธ์ที่อ่านได้ถึงระดับ 12~16% ไม่ใช่ 20~25% การทดสอบยังจำกัด และระหว่างใส่ implementation ของ Mistral ผมทำ implementation ของ Mixtral พัง เลยยังไม่มีข้อมูลที่แน่ชัด แต่ตั้งใจจะแก้เร็ว ๆ นี้
      โดยสัญชาตญาณ ผมมองว่ายิ่งโมเดลใหญ่ ก็ยิ่งตัด effort ออกได้มากขึ้น
      ตอนแรกผมก็เดาเหมือนกันว่าการข้ามการคูณจะทำให้เกิด bias แต่ผิดจากสัญชาตญาณ มันไม่ได้เป็นแบบนั้น มีกราฟอยู่บ้าง แต่ยังไม่พร้อมสำหรับเผยแพร่
      เนื่องจากค่าต่าง ๆ ในเมทริกซ์กระจายอยู่ทั้งบวกและลบอย่างสม่ำเสมอ หลังผ่าน threshold หนึ่งไปแล้ว drift ของค่าผลลัพธ์จึงไม่มาก
  • ดูยอดเยี่ยมมาก แต่ latency 15ms นั้นใกล้กับ 16.7ms ของ vertical sync ที่ 60Hz
    ถ้ากำลังอัปเดตหน้าจอทุกโทเคน อาจเป็นสาเหตุที่ทำให้เกิดการ sync ที่ไหนสักแห่งก็ได้

    • ไม่ใช่ครับ ผมวัดงานของ CPU และ GPU แยกกัน และ 15ms เกิดขึ้นระหว่างการเรียก kernel ต่อให้ไม่พิมพ์ข้อความออกมาก็เกิดขึ้น
      แต่ก็ขอบคุณสำหรับไอเดียครับ จะถือว่าเป็น contribution แรกจากชุมชน :D
  • เป็น contribution ที่ยอดเยี่ยมและเปิดกว้างจริง ๆ ผมจะจับตาดูว่า llama.cpp จะนำสิ่งนี้ไป implement หรือไม่
    ผมกำลังหาวิธีทำให้การอนุมานบน CPU เร็วขึ้น และชอบไอเดียเรื่อง effort มาก

    • การพัฒนาสิ่งนี้เหมือนการวิ่งมาราธอน และดีใจที่ได้ขึ้นหน้าแรก
      ชื่อนี้ chatgpt เป็นคนเสนอ พอมันบอกว่าไม่รู้จักแนวทางนี้ ก็เป็นไปได้ว่ามันอาจเป็นของใหม่จริง ๆ
      ผมอยากติดต่อ llama.cpp และโปรเจกต์อื่น ๆ และหวังว่าจะมีการ implement เคยคิดว่าจะเขียนแพตช์ให้ llama เองด้วย แต่ C++ กับขนาดของโปรเจกต์นั้นหนักเกินไปสำหรับผม
      การอนุมานบน CPU ก็น่าจะเร็วขึ้นเช่นกัน ยิ่งกว่านั้น เนื่องจากสามารถโหลดน้ำหนักเพียงบางส่วน เช่น ข้ามส่วนที่สำคัญน้อยกว่าแล้วโหลดแค่ 70% ได้ จึงน่าจะรันโมเดลด้วย VRAM น้อยกว่าเดิมได้ อย่างไรก็ตาม ยังจำเป็นต้องมี implementation แบบ Q8
      ที่น่าสนใจคือ ตอนพยายามเทียบ benchmark กับ llama.cpp ผมหาความเร็ว 7B/FP16 บน MB Air 16GB ไม่เจอ เพราะโดยวิธีทั่วไปมันรันไม่ได้ แต่ด้วย Effort ทำได้
      ในทำนองเดียวกัน ผมรัน Mixtral ความละเอียดเต็มแต่ถูกตัดทอนบน M2 96GB ได้ ปกติต้องใช้ RAM 114GB แต่เมื่อโหลดน้ำหนักแค่ 75% มันทำงานได้ลื่น ตอนนี้ implementation พังไปนิดจนให้เอาต์พุตขยะอยู่ เลยต้องแก้ก่อน
  • เป็นบทความที่ดี ผมสงสัยจริง ๆ ว่า ประสิทธิภาพต่อ VRAM เมื่อเทียบกับการ quantization แบบง่าย ๆ เป็นอย่างไร
    และก็สงสัยด้วยว่ามีแผนจะ implement เวอร์ชันข้ามแพลตฟอร์มหรือไม่

    • ประสิทธิภาพต่อ VRAM ไม่ได้ดีกว่ามาก เพราะโครงสร้างยังคงใช้น้ำหนักทั้งหมด เพียงแต่ไม่ได้ใช้ทั้งหมดเสมอไป
      แน่นอนว่าสามารถโหลดน้ำหนักให้น้อยลงได้ แต่ถ้าตัดน้ำหนักออกเกิน 20~30% คุณภาพดูเหมือนจะแย่ลงอย่างรวดเร็ว
      กล่าวอีกอย่างคือ อัลกอริทึมนี้แยกเวลาอนุมานออกจากการใช้ VRAM
      ถึงอย่างนั้น ผมเองก็สงสัยว่าเมื่อใช้ effort แล้ว Q8 ที่ตัดเหลือ 75% จะให้ผลลัพธ์ดีกว่า Q6 ได้หรือไม่
      แต่คงต้องใช้เวลาอีกหลายสัปดาห์กว่าจะขัด implementation ให้พอทดสอบได้อย่างถูกต้อง
  • วิธีนี้ไม่ได้ retrain แต่ผมสงสัยว่าถ้าใช้แนวทางแบบนี้ร่วมกับ quantization แล้วค่อยฝึกเพิ่มเติมภายหลัง จะกู้คุณภาพที่เสียไปกลับมาได้บางส่วนหรือไม่
    ดีที่ได้เห็นอะไรแบบนี้ และดีที่ช่วยให้จินตนาการได้ว่าต่อไปประสิทธิภาพและต้นทุนจะปรับปรุงได้แค่ไหน ขอบคุณที่พัฒนาเป็นโอเพนซอร์ส

    • มองเผิน ๆ ก็น่าจะเป็นไปได้ จากที่อ่านมา วิธีหลักในการกู้คุณภาพบางส่วนจาก quantization มีสองแบบ
      แบบหนึ่งคือการฝึกหลังจากนั้น และอีกแบบคือ quantization-aware training ที่ทำ quantization ระหว่างการฝึก แต่ยังคง activation และ gradient ไว้ที่ความละเอียดเต็ม