10 คะแนน โดย GN⁺ 2025-02-28 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • ในช่วงไม่กี่ปีที่ผ่านมา Elixir กำลังขยายขีดความสามารถด้านแมชชีนเลิร์นนิงและข้อมูลผ่านโครงการ Nx (Numerical Elixir)
  • มีโครงการอย่าง Nx, Explorer, Axon, Bumblebee และ Scholar เกิดขึ้น และกำลังพัฒนาบนพื้นฐานของบทเรียนที่ได้จากระบบนิเวศ Python และ R
  • ในช่วงแรกมีการตัดสินใจว่าจะไม่พึ่งพาไลบรารี Python โดยตรง เพื่อมุ่งสู่การออกแบบที่เหมาะกับ Elixir และหลีกเลี่ยงความซับซ้อนของการตั้งค่าสภาพแวดล้อม Python
  • แต่ปัจจุบัน สิ่งที่ขับเคลื่อนการ นำ Elixir มาใช้ ในด้านนี้คือ Livebook
    • เป็นแพลตฟอร์มโน้ตบุ๊กที่อยู่แนวหน้าด้านความสามารถทำซ้ำได้ การประมวลผลแบบกระจาย และการพัฒนาแอป โดยอาศัย จุดแข็งของ Elixir และ Erlang
    • ผ่าน Livebook ความสนใจจากทีมและบริษัทที่ต้องการก้าวเข้าสู่ระบบนิเวศ Elixir เป็นครั้งแรกกำลังเพิ่มขึ้นเรื่อย ๆ
  • แต่ก็ยังมีอุปสรรค
    • บริษัทส่วนใหญ่ที่ต้องการนำ Elixir และ Livebook ไปใช้ในโครงสร้างพื้นฐาน ใช้งานเวิร์กโฟลว์ แพ็กเกจ และรีโพซิทอรีที่อิง Python อยู่แล้ว
    • นั่นหมายความว่าต้องหาแพ็กเกจที่เทียบเท่าใน Elixir หรือเขียนขึ้นใหม่ตั้งแต่ต้น ซึ่งเพิ่มทั้งความเสี่ยงและต้นทุนของการเพิ่ม Elixir เข้าไปใน data stack
  • เพื่อแก้ปัญหานี้ จึงมีการประกาศ Pythonx ซึ่งฝัง Python interpreter ไว้ภายใน Erlang VM

Pythonx

  • Pythonx มีความสามารถในการแปลงข้อมูลอัตโนมัติระหว่าง Elixir กับ Python, การประเมินโค้ด และการจัดการ virtual environment
  • สามารถใช้แพ็กเกจ pytesseract เพื่อทำ Optical Character Recognition (OCR) ได้
  • หลังจากดาวน์โหลดรูปภาพด้วย req แล้ว สามารถเรียก Pythonx.uv_init/1 เพื่อดาวน์โหลดและเริ่มต้น Python พร้อม dependency
  • ใช้ Pythonx.eval/2 เพื่อรันโค้ด Python และแปลงผลลัพธ์เป็นสตริงของ Elixir

โครงสร้างภายใน

  • อิมพลีเมนเทชันอ้างอิง CPython ของ Python สามารถฝังลงในแอปพลิเคชันอื่นได้
  • ความสามารถหลักของ Python interpreter ถูกจัดเตรียมในรูปของไลบรารี C
  • แอปพลิเคชัน C/C++ สามารถลิงก์ไลบรารีดังกล่าวและใช้ API เพื่อรันโค้ดและโต้ตอบกับอ็อบเจ็กต์ได้
  • Elixir มีการทำงานร่วมกับ C/C++ ผ่าน Erlang NIFs
  • Pythonx ใช้ NIFs ในการฝัง Python และทำงานอยู่ใน OS process เดียวกัน
  • การส่งผ่านข้อมูลระหว่าง Python กับ Elixir จึงทำได้อย่างมีประสิทธิภาพ

การรองรับหลายภาษาใน Livebook

  • ขณะนี้กำลังเพิ่มการรองรับ Python ใน Livebook โดยอาศัย Pythonx
  • ทำให้ Elixir และ Python สามารถโต้ตอบกันได้ภายในโน้ตบุ๊กเดียวกัน
  • Livebook จะติดตั้ง Python และ dependency ให้โดยอัตโนมัติ และจัดการการแปลงระหว่างตัวแปรของ Elixir กับ Python
  • ช่วยรับประกันสภาพแวดล้อมที่ทำซ้ำได้
  • ขณะนี้ยังมีงานเพิ่มเติม เช่น code completion และเอกสารประกอบที่กำลังดำเนินอยู่ และสามารถดาวน์โหลด Livebook nightly มาใช้งานได้

สิ่งที่ควรพิจารณาในการใช้งานและทางเลือกอื่น

  • จุดประสงค์หลักของ Pythonx คือการผสานเวิร์กโฟลว์ Python เข้ากับ Livebook และสคริปต์
  • เนื่องจาก global interpreter lock (GIL) ของ Python จึงอาจมีข้อจำกัดด้าน concurrency เมื่อหลาย Elixir process เรียก Pythonx
  • ควรเรียกจาก Elixir process เดียว หรือยืนยันว่าไลบรารี Python ที่ใช้สามารถรองรับการเรียกพร้อมกันได้
  • อีกทางเลือกหนึ่งคือใช้ System.cmd/3 หรือ Port เพื่อจัดการหลาย Python process
  • สำหรับเวิร์กโฟลว์ AI สามารถใช้ Bumblebee เพื่อรันโมเดลที่ฝึกไว้ล่วงหน้าได้
  • สามารถใช้ Ortex เพื่อรันโมเดล ONNX ได้
  • สำหรับ LLM สามารถใช้ third-party API หรือรันคอนเทนเนอร์ Llama.cpp Docker แบบ on-premises ได้
  • หากใช้อินเทอร์เฟซแบบ HTTP ก็สามารถใช้เครื่องมืออย่าง Instructor และ LangChain ของ Elixir ได้

โครงการ Fine

  • Pythonx ถูกพัฒนาด้วย NIFs
  • NIFs คือฟังก์ชัน Elixir ที่เขียนด้วย C และต้องใช้โค้ด boilerplate จำนวนมาก
  • มีความซับซ้อนทั้งด้านการจัดการหน่วยความจำและการจัดการข้อผิดพลาด
  • เพื่อแก้ปัญหานี้ จึงมีการพัฒนาไลบรารี Fine ที่อิงกับ C++
  • Fine มีความสามารถในการจัดการการแปลงโครงสร้างข้อมูลโดยอัตโนมัติ การดูแล resource object อย่างปลอดภัย และการ throw exception
  • จึงช่วยลดปริมาณโค้ดที่ต้องเขียนเมื่อสร้าง NIF ได้อย่างมาก

บทสรุป

  • เป้าหมายของโครงการ Numerical Elixir คือทำให้ Elixir มีอัตลักษณ์ของตัวเองในระบบนิเวศด้านข้อมูลและแมชชีนเลิร์นนิง
  • ตอนนี้การทำงานร่วมกันข้ามระบบได้กลายเป็นเป้าหมายสำคัญ
  • Pythonx ทำให้สามารถฝัง Python ลงใน Elixir และเปิดให้เกิดการแปลงข้อมูลระหว่างสองภาษาได้อย่างโปร่งใส

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

 
aer0700 2025-03-01

NumPy ดีจริงๆ...

 
GN⁺ 2025-02-28
ความเห็นบน Hacker News
  • ฟีเจอร์ของ Livebook เจ๋งมาก การเรียกใช้ CPython โดยตรงจาก Elixir ผ่าน C++ NIFs และคืนค่าเป็นโครงสร้างข้อมูลแบบเนทีฟของ Elixir ดูสะอาดมาก

    • บนเซิร์ฟเวอร์โปรดักชัน การใช้ Pythonx อาจมีความเสี่ยงอยู่บ้าง เพราะมันรันอยู่ใน OS process เดียวกับแอป Elixir ทำให้ข้ามความสามารถด้านการกู้คืนความล้มเหลวอันแข็งแกร่งของแอป Elixir/BEAM ไป
    • โดยทั่วไป แอป Elixir จะมี supervision tree ที่สามารถจัดการกับความล้มเหลวของ BEAM process ของตัวเองได้อย่างสวยงาม ซึ่งเป็นข้อดีสำคัญของภาษาอย่าง Elixir, Erlang และ Gleam
    • เมื่อใช้ NIFs หากเกิด exception ที่ไม่ได้ถูกจัดการใน Pythonx ก็อาจทำให้ทั้ง OS process และทุก BEAM process หยุดทำงานได้
    • Rustler เป็น NIF wrapper สำหรับ Rust ที่ได้รับความนิยมใน Elixir และแม้ NIFs จะมีประโยชน์มากในหลายกรณี แต่ก็ควรคำนึงถึงความเสี่ยงที่อาจทำให้ทั้งแอปหยุดทำงาน
    • การใช้ Ports เพื่อรัน native code อื่นอย่าง Python หรือ Rust มีความเสี่ยงน้อยกว่าในแง่นี้
  • เป็นเรื่องดีที่ได้เห็นคน "ที่เป็นที่รู้จักกันดี" ในคอมมูนิตี้ Elixir สนับสนุนแนวทางนี้และพัฒนาอย่างจริงจัง

    • VM และรันไทม์เหมาะมากกับการประสานงานภาษาและเทคโนโลยีอื่น ๆ จนให้ความรู้สึกเหมือนมีทั้งเส้นทางมาตรฐานและเส้นทาง offload
    • ความต่างระหว่างไอเดีย offload ที่ "ดูเสี่ยง" กับการรันอย่างปลอดภัย มักเป็นเพียงเรื่องของปริมาณงาน แต่รันไทม์ก็สนับสนุนแนวทางนี้
    • เพราะมันเป็น NIF จึงมีความเสี่ยงอยู่บ้าง แต่สามารถสร้าง BEAM instance แยกต่างหากแล้วกระจายงานผ่านตัวนั้นได้
  • มีคอมเมนต์อื่นที่ชี้ถึงประเด็นความปลอดภัยของการใช้ NIFs

    • Erlang VM scheduler ไม่สามารถ preempt NIF ได้ ดังนั้นการเรียก Python ที่รันนานจึงเสี่ยงทำให้ VM ค้างได้
    • แม้ GIL จะขัดขวางการรัน Python พร้อมกันหลายตัว แต่ฝั่งผู้เรียกจาก Erlang สามารถรัน Python interpreter หลายตัวได้ จึงไม่เป็นปัญหาเมื่อใช้ Ports
  • เป็นบทความที่ให้ข้อมูลมาก ดีที่ระบุชัดเจนว่า Pythonx ไม่ได้เป็นแค่การเรียก subprocess ธรรมดา แต่รันอยู่ใน process เดียวกัน

    • น่าจะดีถ้ามีตัวอย่างเพิ่มเติมเกี่ยวกับการเรียกฟังก์ชันที่นิยามไว้ใน Python จาก Elixir
  • ดีใจที่เห็น Elixir ซึ่งเหมาะกับสงคราม AI มากกว่า JavaScript และ Python กลับยังตามหลังอยู่

    • ชอบการตัดสินใจตั้งแต่แรกในการขยายพื้นฐาน ML ของ Elixir เอง แต่ก็ดีที่ตอนนี้มีวิธีใช้ประโยชน์จากไลบรารี Python ที่พัฒนาอย่างรวดเร็วได้ด้วย
  • ก่อนหน้านี้การก้าวจาก Python เข้าสู่ ecosystem ของ Elixir/Erlang รู้สึกยากเกินไป แต่ด้วย Pythonx การเรียนรู้แบบค่อยเป็นค่อยไปดูเป็นไปได้มากขึ้น

    • สงสัยว่าได้ลองทดสอบ free threading กับปัญหา GIL ของ Python หรือยัง
  • Elixir มีฟีเจอร์บางอย่างที่อยากให้มีใน Python

    • atom, การที่แทบทุกอย่างเป็น macro, pipe |>, immutability ที่แท้จริง, parallelism และ concurrency ที่แท้จริงด้วย supervision tree, hot code reloading, fault tolerance
  • ในฐานะคนที่คลุกคลีกับ Elixir ลึกพอสมควรและใช้ Python อย่างมาก คิดว่านี่ใช้งานได้จริงมาก

    • สนใจ Fine library มากกว่า ซึ่งช่วยให้สร้าง C++ NIFs ใน Elixir ได้ง่าย
  • โปรเจกต์นี้และบล็อกโพสต์นี้ให้ความรู้สึกเหมือนสร้างมาเพื่อฉันเลย อยากลองใช้ดู ขอบคุณ