1 คะแนน โดย GN⁺ 2023-07-24 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • llama2.c คือโซลูชันการฝึกและการอนุมานแบบ “fullstack” ที่ฝึกสถาปัตยกรรม Llama 2 LLM ด้วย PyTorch และรันการอนุมานด้วยไฟล์ C แบบเรียบง่าย run.c
  • จุดโฟกัสหลักคือ ความมินิมอลและความเรียบง่าย โดยเป็น implementation เชิงการศึกษาที่ฮาร์ดโค้ดสถาปัตยกรรม Llama 2 และประกอบด้วยไฟล์อนุมาน C ล้วนไฟล์เดียวที่ไม่มี dependency
  • มีโมเดลตัวอย่างบนพื้นฐาน TinyStories โดยยึดแนวคิดว่าแม้แต่ LLM ขนาดเล็กมากก็ยังให้ประสิทธิภาพที่ดีได้ หากจำกัดโดเมนให้แคบพอ
    • โมเดล 15M พารามิเตอร์มีขนาดดาวน์โหลดราว 60MB และสามารถรันได้ด้วย make run แล้วตามด้วย ./run stories15M.bin
    • ยังมีโมเดล 42M และ 110M พารามิเตอร์ให้ด้วย โดยระบุว่าโมเดล 110M มีขนาดเท่ากับ GPT-1
  • โมเดล Llama 2 ของ Meta ก็สามารถรันการอนุมานได้เช่นกันเพราะใช้สถาปัตยกรรมโครงข่ายประสาทแบบเดียวกัน แต่ต้องรับ checkpoint ตามแนวทางของ Meta ก่อน แล้วแปลงเป็นฟอร์แมตของ llama2.c ด้วย export.py
    • ปัจจุบัน run.c รองรับเฉพาะการอนุมานแบบ fp32 ดังนั้นโมเดลที่ใหญ่กว่า 7B อาจโหลดมาใช้งานจริงได้ยาก
    • รุ่น 13B ขึ้นไปยังไม่ทำงานในตอนนี้เพราะ integer overflow ใน pointer arithmetic และยังไม่ได้แก้ไข
  • การอนุมานแบบ int8 quantization ถูก implement ไว้ใน runq.c โดยใช้วิธี Q8_0 เพื่อ quantize น้ำหนักที่เข้าร่วม matmul และยัง quantize/dequantize ค่า activation แบบไดนามิกในรันไทม์
    • การ export แบบ fp32 ของ Llama 2 7B จะสร้างไฟล์ขนาด 26GB ส่วน quantized export version 2 จะสร้างไฟล์ขนาด 6.7GB
    • ในสภาพแวดล้อมของผู้เขียน เมื่อใช้ OpenMP 64 เธรด fp32 ทำได้ 4.6 tok/s และ int8 ทำได้ 14 tok/s ทำให้ checkpoint มีขนาดเล็กลง 4 เท่าและเร็วขึ้นราว 3 เท่า
  • วิธีใช้งานครอบคลุมการรัน C inference, การป้อนพรอมป์ต์, การควบคุม sampling แบบ temperature และ top-p, การรันโหมด chat และการระบุ tokenizer แบบกำหนดเอง
    • ตัวอย่างการรันคือ ./run stories42M.bin -t 0.8 -n 256 -i "One day, Lily met a Shoggoth"
    • โมเดล chat รันด้วยแฟลก -m chat เช่น ./run llama2_7b_chat.bin -m chat
    • tokenizer แบบกำหนดเองสามารถ export เป็นฟอร์แมต .bin ด้วย tokenizer.py แล้วระบุผ่านแฟลก -z
  • โมเดลบน Hugging Face ที่ใช้สถาปัตยกรรม Llama 2 สามารถ export เป็นไฟล์ .bin ได้ด้วยแฟลก --hf ของ export.py
  • เวิร์กโฟลว์การฝึกเริ่มจากดาวน์โหลดและ pre-tokenize TinyStories จากนั้นรัน train.py แล้ว export โมเดลเพื่อนำไปอนุมานต่อใน C
    • ขณะนี้ตัวอย่าง TinyStories พื้นฐานเป็นตัวอย่างชุดข้อมูลเดียวที่มีให้
    • การฝึก tokenizer แบบกำหนดเองใช้ sentencepiece โดยในตัวอย่างใช้การตั้งค่า --vocab_size=4096
  • การ build ด้านประสิทธิภาพแบ่งเป็น make run, make runfast และ make runomp โดย build แบบ OpenMP จะเปิดใช้ #pragma omp parallel for ภายใน matmul และ attention เพื่อกระจายงานในลูปไปยังหลายโปรเซสเซอร์
  • มีคำแนะนำการ build สำหรับ Windows, Centos 7, Amazon Linux 2018 และ Mac
    • Windows ใช้ build_msvc.bat หรือ make win64
    • Centos 7 และ Amazon Linux 2018 ใช้ make rungnu หรือ make runompgnu
    • OpenMP build บน Mac ใช้ make runomp CC=/opt/homebrew/opt/llvm/bin/clang หลังติดตั้ง clang จาก brew
  • มีการทดสอบด้วย pytest และ C test make testcc โดย test_all.py จะรัน forward 200 สเต็ปทั้งใน C และ Python แล้วเปรียบเทียบกับผลลัพธ์คาดหมายที่ทราบอยู่แล้ว
  • เป้าหมายของโปรเจ็กต์คือคงความเป็น reference implementation แบบเรียบง่ายที่ประกอบด้วยไฟล์ .py สำหรับการฝึก 2 ไฟล์ที่อ่านง่าย และโค้ดอนุมาน C โดยไม่มุ่งไปทางเฟรมเวิร์กซับซ้อนหรือออปชันจำนวนมาก
  • ไลเซนส์คือ MIT

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

 
GN⁺ 2023-07-24
ความคิดเห็นจาก Hacker News
  • เห็นโพสต์นี้บน HN แล้วน่าสนใจดี :) เดิมทีเช็กพอยต์นี้เมื่อคอมไพล์ด้วย -O3 บน MacBook Air M1 จะรันได้เร็วถึง 100 tok/s ซึ่งเร็วกว่าที่คาดมาก ตอนนี้เลยกำลังฝึกโมเดล 44M ที่ใหญ่ขึ้นอยู่
    ถึงอย่างนั้นก็น่าจะยังรันแบบโต้ตอบได้ และก็รู้สึกว่าอาจเอื้อมถึงโมเดล 7B ของ Llama ได้เหมือนกัน

    • ลองแก้ nanoGPT นิดหน่อยแล้วพรีเทรนโมเดล 12M ด้วยข้อมูล 2GB ที่ GPT-4 สร้างจาก TinyStories ผลลัพธ์ออกมาน่าประหลาดใจทีเดียว
      หลังจากนั้นพอปรับให้เข้ากับ Wikipedia อีกเล็กน้อย มันก็กลายเป็นตัวสร้างเรื่องเพ้อเจ้อที่ดูน่าเชื่อถือ ซึ่งฉลาดกว่าและเล็กกว่าระบบ n-gram แบบทำ smoothing มาก ดูเหมือนว่า LLM ขนาดเล็กจะกลายเป็นกระแสหลักในหลายด้าน และเป้าหมายถัดไปคือย่อ Llama2 7B ให้เหลือ 10~100M โดยไม่ให้มันโง่ลงมากเกินไป
    • งานแบบนี้ให้แรงบันดาลใจเสมอ ขอถามแบบมือใหม่หน่อยว่า เส้นทางที่ใช้งานได้จริงที่สุดในการรัน LLM ขนาดพอเหมาะสำหรับเว็บแอปงานอดิเรกบน เซิร์ฟเวอร์ Linux ทั่วไปที่ไม่มี GPU แรง ๆ คืออะไร
      การเช่า GPU instance จากที่อย่าง Linode แพงกว่าการเช่าเซิร์ฟเวอร์เว็บแอปทั่วไปมาก เลยอยากรู้ว่านี่เป็นพื้นที่ที่เป็นไปไม่ได้เลยหรือเปล่า หรือแนวทางแบบนี้รวมถึงวิธีอื่น ๆ ยังพอเป็นทางที่ใช้งานได้จริง
    • อยากรู้ว่ามีความเห็นเบื้องต้นไหมเกี่ยวกับคุณภาพ/ประสิทธิภาพสัมพัทธ์ของ Llama-2 ขนาดเล็ก เทียบกับ GPT-2 ขนาดเล็ก
    • อยากรู้ว่าคิดว่าน่าจะทำ เทรนเนอร์แบบ C ล้วน แทน Python ได้ไหม
    • อยากรู้ว่าโมเดลพวกนี้ฝึกกันที่ไหน ระหว่างเครื่องที่บ้าน, M1, หรือคลาวด์
  • Georgi Gerganov ผู้โด่งดังจาก llama.cpp มีเวอร์ชันที่รันบนเบราว์เซอร์ด้วย Emscripten: https://ggerganov.com/llama2.c/
    Twitter thread ที่กำลังดำเนินอยู่คือ https://twitter.com/ggerganov/status/1683174252990660610
    ทั้งต้นฉบับและงานนี้ยอดเยี่ยมมาก และแม้จะใกล้เคียงกับการพิสูจน์แนวคิดที่ใช้โมเดลเล็กมาก แต่ LLM แบบ local-first ก็น่าสนใจเป็นพิเศษ ชอบแนวคิดที่ว่าสามารถสร้างเว็บแอปด้วย local inference ได้
    ถ้าต่อยอดไปถึงการปรับแต่งประสิทธิภาพ งานวิจัยโมเดลที่เล็กลง การดาวน์โหลดบางส่วน และการใช้ WebGPU ก็อาจเป็นจุดเริ่มของแนวทางใหม่ในการสร้างแอปส่วนตัวที่อิงกับ LLM ในเครื่อง แม้อาจยากที่จะมีความสามารถเทียบเท่า LLM ที่โฮสต์บนคลัสเตอร์ GPU ระดับสูงขนาดใหญ่ แต่แนวทางนี้ก็น่าจะเปิด use case ได้อีกมาก

    • ลิงก์แรกให้ผลลัพธ์ที่แปลกพอสมควร ตอนแรกมันเริ่มเหมือนนิทานที่พอเชื่อได้ แต่จากนั้นก็มีคำพิมพ์ผิดมากขึ้น พูดวกวนจนเสียทรง แล้วเริ่มปนภาษาต่างประเทศกับศัพท์เทคนิค/โปรแกรมมิงออกมา
      ตัวอย่างเช่นเริ่มด้วย “Once upon a time...” แล้วดูเหมือนจะเป็นเรื่องของ Lily กับ Timmy แต่จากนั้นก็กลายเป็นข้อความเพี้ยน ๆ อย่าง “Butterfly would pauseWhy”, “TextField”, querySelector, HttpRequest และเศษข้อความจากหลายภาษาที่ปนกันจนเละ
  • สำหรับคนที่สงสัย มี เวอร์ชัน Rust ด้วย ในโหมด release ได้ประมาณ 106 tokens/second
    https://github.com/garrisonhess/llama2.c/blob/517a1a3e487f31...

    • ยังมีเวอร์ชัน Rust อีกตัว ใช้ ไลบรารี candle ML ที่กำลังทำอยู่ตั้งแต่เดือนก่อน และรันบนเบราว์เซอร์ได้ด้วย: https://laurentmazare.github.io/candle-llama2/index.html
      เวอร์ชันที่ไม่ใช่เว็บรองรับ GPU อย่างเต็มที่ แต่ไม่ได้มินิมอลเลยแม้แต่น้อย
    • อย่างที่เห็นบ่อยใน Rust บางครั้งก็มีการย้ายของที่มีอยู่แล้วมาเขียนใหม่เพียงเพราะมันทำได้ โดยไม่ได้ให้ประโยชน์อะไรเพิ่มเลย
      บางครั้งยังทำให้ความพยายามของชุมชนในการ กระจาย การปรับปรุงโปรเจกต์ด้วย
  • ดูเหมือนจะมีไม่มากนักที่เข้าใจว่านี่เป็นก้าวเดินที่กล้าหาญแค่ไหน
    Andrej ได้ค่าตอบแทนก้อนโตจาก OpenAI(MSFT) แต่ก็ยังช่วย Apple, Facebook และที่สำคัญกว่านั้นคือ ขบวนการโอเพนซอร์ส ด้วย ถึงอย่างนั้นก็คงยากที่จะกันเขาออกไปได้ เพราะถ้าเป็นแบบนั้นเขาก็อาจย้ายไป Tesla หรือ xAI ได้ทันที

  • รู้สึกว่า Llama-2 มี การกรองความปลอดภัย หนักเกินไปจนเอาไปใช้กับงานสร้างสรรค์ไม่ได้: https://i.imgur.com/GFY0wSL.png

    • ส่วนตัวคิดว่าภายใต้ชื่อของ “ความปลอดภัย” มันกลับหมุนไปอีกทางจนถึงขั้นเสริมแรงภาพเหมารวมที่เกลียดชังหรือเป็นลบได้เลย เพราะกรองหนักเกินไป: https://i.imgur.com/xkzXrPK.png และ https://i.imgur.com/3HQ8FqL.png
      อย่างไรก็ตาม ปรากฏการณ์นี้พอจะทำซ้ำได้เฉพาะตอนส่งเป็นข้อความที่สองบน Llama2-70b-chat TGI ของ Hugging Face และอาจเป็นไปได้ว่ามีอะไรแปลก ๆ ในวิธีพรอมป์ต์จนทำให้เกิดพฤติกรรมแบบนี้ ตอนนี้ยังไม่ได้รันโมเดลเองเพื่อตรวจสอบเพิ่มเติม
    • ถ้ามีโมเดลพรีเทรน ก็ควรหลีกเลี่ยงการใช้ instruct/chat model
      Chat/instruct มีข้อดีตรงที่ปล่อยให้ผู้ใช้ภายนอกใช้งานได้ง่าย พรอมป์ต์ไม่ซับซ้อน และมีราวกันความปลอดภัย แต่ถ้าใช้เอง มันด้อยกว่าโมเดลพรีเทรนอย่างมาก ตรงนี้ Llama 2 อาจได้เปรียบ OpenAI เพราะ OpenAI ดูเหมือนจะเลิกใช้โมเดลพรีเทรน GPT-3 และมุ่งไปทางให้บริการเฉพาะ chat model ต่อไป
    • ลองนึกภาพว่า Casca กับ Brutus ไม่ได้แทง Caesar แต่เลือกเผชิญหน้าเขาอย่างสุภาพเกี่ยวกับความเป็นไปได้ที่เขาจะใช้อำนาจในทางที่ผิดและแนวโน้มแบบเผด็จการของเขา
    • สิ่งที่กรองเกินไปไม่ใช่ “llama-2” ทั้งหมด แต่คือ Llama-2 chat
    • ควรผลักคนสาย “Ethical AI” ออกไปได้แล้ว เห็นชัดขึ้นเรื่อย ๆ ว่าพวกเขาน่ารำคาญจริง ๆ
      ไม่ต้องการกรรไกรเซฟตี้ จะจำกัดสิ่งที่รันบนเซิร์ฟเวอร์ของตัวเองก็เรื่องหนึ่ง แต่อย่าเอาโมเดลที่ฉันแก้ไขและใช้ตามต้องการบนคอมพิวเตอร์ของตัวเองไม่ได้มาให้
  • Andrej โพสต์รายละเอียดเพิ่มเติมไว้ที่นี่: https://twitter.com/karpathy/status/1683143097604243456?s=46...

  • อนึ่ง ถ้าสนใจเรื่องแนวนี้ โค้ดนี้สามารถบิลด์ด้วย WASI SDK ได้อย่างเรียบร้อย และรันบน Wasm runtime ได้โดยไม่ต้องแก้ไข

  • สงสัยว่าถ้าจะรันโครงข่ายประสาทเทียมต้องใช้หน่วยความจำเท่าไร
    แค่อ่านสองเลเยอร์แรกจากดิสก์ คำนวณค่า activation ของทุกโหนด จากนั้นทิ้งเลเยอร์แรก แล้วอ่านเลเยอร์ที่สามมาคำนวณต่อ แล้วทิ้งเลเยอร์ที่สอง แบบนี้ก็พอหรือไม่? ถ้าใช่ ก็สงสัยว่ามีหน่วยความจำพอแค่เก็บสองเลเยอร์ก็พอหรือเปล่า

    • TheBloke ของ Hugging Face ได้ทำเอกสารความต้องการหน่วยความจำแยกตาม เวอร์ชันที่ถูกควอนไทซ์ ของโมเดลยอดนิยมไว้: https://huggingface.co/TheBloke
      สรุปคือ RAM สูงสุดขึ้นอยู่กับวิธีควอนไทซ์ โดยคร่าว ๆ โมเดล 7B อยู่ที่ 4~8GB, 13B อยู่ที่ 8~15GB, 30B อยู่ที่ 13~33GB และ 70B อยู่ที่ 31~75GB
    • ไม่จำเป็นต้องจัดการอ่านแล้วทิ้งเองโดยตรง แค่ mmap ทั้งเครือข่ายแล้วปล่อยให้ระบบปฏิบัติการจัดการก็ได้
    • ทำได้ แต่ถ้าทำแบบนั้นจะติดข้อจำกัดที่ แบนด์วิดท์ดิสก์
    • เท่าที่ทราบ ใน transformer inference แบบ O(N²) จำเป็นต้องแคชค่า activation ทั้งหมดไว้
  • มีความคิดแวบขึ้นมาว่า ตอนนี้ LLM คืนค่าการกระจายความน่าจะเป็นออกมา แล้วตัวสุ่มก็เลือกหนึ่งค่าไปต่อท้ายผลลัพธ์แล้วทำซ้ำ
    ถ้าเปลี่ยนเป็นให้ตัวสุ่มเลือกโทเค็น N ตัวที่ประมาณการกระจายนั้น แล้วให้ LLM สร้างการกระจายใหม่ N ชุด จากนั้นรวมมันด้วยวิธีใดวิธีหนึ่ง แล้วเลือกโทเค็น N ตัวอีกครั้งจากการกระจายที่รวมกัน แบบนี้จะเป็นไปได้ไหม?

    • ฟังดูคล้าย beam search มาก และก็เป็นเทคนิคการสร้างข้อความที่ใช้กันทั่วไปจริง ๆ: https://en.wikipedia.org/wiki/Beam_search
      ดูตัวอย่างได้ที่ https://huggingface.co/docs/transformers/internal/generation...
    • ฟังดูเป็นแนวทางที่น่าศึกษา แต่คงต้องสร้างล่วงหน้าไกลกว่า 2 โทเค็นมาก อาจจะมองล่วงหน้าสัก 20 โทเค็น แต่ก็คงไม่อยากรัน LLM ถึง N^20 ครั้ง ดังนั้นอาจดีกว่าถ้าจะสุ่มตัวแทนสัก 200 ชุดจากชุดผสมของ 20 โทเค็นถัดไป
      แต่ก็ไม่รู้ว่าจะทำอย่างไร
    • แม้จะยังใหม่ แต่ชอบไอเดียนี้ ไม่รู้คำตอบเหมือนกัน แต่ก็ดูน่าลองทดลอง และมีโอกาสสูงที่นักวิจัยน่าจะเคยลองแล้ว
      แน่นอนว่าแต่ละการสร้างโทเค็นจะต้องใช้ การคำนวณเพิ่ม N เท่า อาจเลือก N อันดับแรก หรือถ้าจำเป็นก็ปรับอุณหภูมิที่ logits แล้วสุ่ม N ตัวออกมาได้
  • อันนี้มีไว้เพื่อการศึกษาหรือ? เมื่อดูความสำเร็จของ llama.cpp และโปรเจกต์นี้ ก็เหมือนว่าอุตสาหกรรมกำลังไปในทางมี ซอร์สโค้ดแยกเฉพาะ สำหรับแต่ละโมเดลที่ออกมา แทนการใช้เฟรมเวิร์กอเนกประสงค์อย่าง PyTorch, TensorFlow, ONNX Runtime

    • อันนี้ดูเหมือนมีไว้ เพื่อการศึกษา ล้วน ๆ
      และไม่ใช่แบบนั้นทั้งหมด ตามชื่อแล้ว llama.cpp ก็ไม่ได้รองรับแค่ llama และก็ไม่ได้เฉพาะทางเต็มตัว เพราะสร้างอยู่บนไลบรารี/เฟรมเวิร์กเทนเซอร์ ggml ที่มีความทั่วไปมากกว่า
    • ต่อให้อยู่ในเฟรมเวิร์ก ก็ยังมีซอร์สโค้ดแยกตามโมเดลอยู่ดี เพราะโมเดลเป็น โค้ดที่ปรับแต่งเฉพาะ จากการประกอบบล็อกพื้นฐานของเฟรมเวิร์ก ไม่ได้ถูกสร้างขึ้นจากเฟรมเวิร์กแบบล้วน ๆ นี่เป็นธรรมชาติของงานวิจัยเชิงสำรวจ
      แต่เมื่อเจอโมเดลที่ใช้งานได้ดีแล้ว ความก้าวหน้าเหล่านั้นก็มักถูกรวมเข้าไปในเฟรมเวิร์กเวอร์ชันถัดไป นั่นจึงเป็นเหตุผลที่ TensorFlow มีบล็อกพื้นฐานอย่าง CNN, GRU, TransformerEncoder และในขณะเดียวกันก็มีการทำ implementation สำหรับฮาร์ดแวร์เฉพาะที่แลกความทั่วไปเพื่อให้ได้ความเร็ว
    • เป็น single-thread ดังนั้นมองว่าเพื่อการศึกษาก็ถูกต้องแล้ว