ข้ามไปยังเนื้อหา
Polars 2.0 RC เปลี่ยน LazyFrame ทุกคิวรีไปวิ่งบน streaming engine เป็นดีฟอลต์ — และ breaking change ที่อันตรายที่สุดคือข้อเดียวที่ไม่ throw error
เครื่องมือนักพัฒนา

Polars 2.0 RC เปลี่ยน LazyFrame ทุกคิวรีไปวิ่งบน streaming engine เป็นดีฟอลต์ — และ breaking change ที่อันตรายที่สุดคือข้อเดียวที่ไม่ throw error

อ่าน 6 นาที ที่มา: Polars

วันที่ 2 ก.ย. 2026 ทีม Polars ปล่อย 2.0.0-rc.1 ซึ่งเป็น release candidate ตัวแรกของเวอร์ชันหลักถัดไป (แท็ก py-2.0.0-rc.1 ขึ้นบน GitHub เวลา 11:49 UTC วันเดียวกัน) และประกาศว่า “The definite 2.0 release will land in the following weeks.” ทดลองได้แล้วด้วย pip install polars==2.0rc1

Polars อาจไม่ใช่ข่าว AI โดยตรง แต่มันเป็นชั้นที่อยู่ใต้งาน AI จำนวนมาก — pipeline เตรียมข้อมูลเทรน การทำฟีเจอร์ การล้างและ dedup ชุดข้อมูล การประมวลผลผลลัพธ์ eval — และการเปลี่ยนแปลงหลักในเวอร์ชันนี้แตะพฤติกรรมที่งานเหล่านั้นพึ่งพาอยู่โดยไม่รู้ตัว

สิ่งที่เปลี่ยน: streaming engine กลายเป็นดีฟอลต์

ของหลักมีข้อเดียวและใหญ่: “Calling collect on a LazyFrame will now default to the streaming engine” คือ ทุกคิวรี LazyFrame จะวิ่งบน streaming engine แทน in-memory engine เดิม โดยทีมระบุว่าผู้ใช้ “can expect huge improvements in memory usage and performance” และคาดว่า “the streaming engine to be easily 5x faster”

ตัวเลข 5 เท่าควรอ่านว่าเป็นความคาดหมายของทีม — โพสต์ประกาศลิงก์ออกไปหาเบนช์มาร์กแทนที่จะแสดงตารางวัดผลในตัวโพสต์เอง จึงยังไม่มีตัวเลขวัดผลติดมากับประกาศให้ตรวจตรงจุด ส่วนฝั่ง SQL มีบันทึกเป็น breaking change ตรง ๆ ในรีลีสโน้ตว่า “Set the default engine for SQL to the streaming engine (#28973)”

ทิศทางนี้สมเหตุสมผลมาก — streaming engine คือสิ่งที่ทีม Polars ลงแรงมาหลายเวอร์ชัน และประโยชน์ที่ชัดที่สุดคือชุดข้อมูลที่ใหญ่กว่าแรมจะไม่ล้มอีกต่อไป ซึ่งตรงกับงาน AI ที่ชุดข้อมูลโตเร็วกว่าเครื่องเสมอ

เหตุผลที่ต้องขึ้นเป็นเวอร์ชัน 2.0 — และมันคือกับดัก

คำอธิบายว่าทำไมต้องขึ้นเวอร์ชันหลัก อยู่ในประโยคเดียวนี้:

“The streaming engine doesn’t guarantee row-order by default for certain operations (join, group_by, unpivot, etc.). If you require observable row-order in those operations, you can opt in to that by setting maintain_order=True.”

นี่คือประเด็นที่คนอ่านผ่านง่ายที่สุดและกัดแรงที่สุด เพราะ breaking change ที่เหลือในชุดนี้ ฟ้องเป็น exception ทั้งหมด:

  • is_in ไม่ยอมแปลงชนิดแบบสูญเสียข้อมูลอีกต่อไป — 2.0 จะโยน InvalidOperationError: 'is_in' cannot check for Int64 values in List(Float64) data.
  • concat แนวนอนตรวจความสูงแล้ว — จะโยน ShapeError: cannot concat dataframes with different heights in 'strict' mode ถ้าอยากได้การเติมเต็มแบบเดิมต้องระบุ how="horizontal_extend" เอง
  • .cast() ไม่รับการแปลงบางแบบแล้ว เช่นสตริง→วันที่ หรือค่าเข้า Enum/Categorical ต้องเปลี่ยนไปใช้เมธอดเฉพาะอย่าง .str.to_date(), .str.to_datetime(), .cat.to(), .cat.physical()

ทั้งสามข้อนี้ พังเสียงดัง — คุณอัปเกรด รัน แล้วเห็น traceback ทันที ซึ่งเป็นการพังแบบที่ดี

ส่วนเรื่องลำดับแถว พังเงียบ ไม่มี error ไม่มี warning โค้ดเดิมรันผ่าน ได้ตัวเลขออกมาเหมือนเดิมทุกอย่าง ยกเว้นลำดับของแถว และถ้า pipeline ของคุณมีขั้นตอนไหนที่พึ่งลำดับแถวโดยปริยาย ผลลัพธ์จะเปลี่ยนโดยไม่มีอะไรบอก จุดที่พบบ่อยในงาน ML/AI คือ:

  • การแบ่ง train/test ด้วยการตัดแถวตามตำแหน่ง (head/slice หลัง group_by หรือ join)
  • การสุ่มตัวอย่างที่ตั้ง seed ไว้ — seed เดิมกับข้อมูลเดิม แต่ลำดับก่อนสุ่มเปลี่ยน ผลก็เปลี่ยน
  • การ dedup หรือทำแฮชของทั้งชุดข้อมูลเพื่อเทียบว่าข้อมูลรอบนี้กับรอบก่อนเหมือนกันไหม
  • ลำดับของ eval set ที่ต้องตรงกันเวลาเทียบผลระหว่างโมเดลสองตัว

ทางแก้ตรงไปตรงมา — ใส่ maintain_order=True ในจุดที่ต้องการ — แต่การจะใส่ได้ต้องรู้ก่อนว่าจุดไหนต้องการ ซึ่งคือส่วนที่ต้องใช้แรงคน

มุมมอง AI Curator

สิ่งที่ทำให้รีลีสนี้น่าเขียนถึงในบล็อก AI ไม่ใช่ตัว dataframe แต่คือรูปร่างของ breaking change ชุดนี้ เมื่อวางในโลกที่โค้ดจำนวนมากถูกเขียนและอัปเกรดโดยเอเจนต์

ลองคิดตามจริง ๆ: ถ้าคุณสั่ง coding agent ว่า “อัปเกรดโปรเจกต์นี้เป็น Polars 2.0” เอเจนต์จะรันเทสต์ เห็น InvalidOperationError เห็น ShapeError เห็น cast ที่ใช้ไม่ได้ แล้วแก้จนเทสต์เขียว — สามในสี่ข้อจบสวยเพราะมันฟ้อง แต่ข้อลำดับแถวจะไม่ปรากฏใน traceback เลย และถ้าเทสต์ในโปรเจกต์ไม่ได้ยืนยันลำดับไว้ตรง ๆ เทสต์ก็ยังเขียว เอเจนต์ก็รายงานว่าอัปเกรดสำเร็จ ความถูกต้องที่หายไปคือความถูกต้องที่ไม่มีใครเขียนเทสต์ไว้ ซึ่งเป็นประเภทที่การอัปเกรดอัตโนมัติจับไม่ได้โดยโครงสร้าง ไม่ใช่เพราะเอเจนต์โง่

มีชั้นที่สองซ้อนอยู่อีก: โค้ด Polars ที่ LLM เขียนออกมาวันนี้ ล้วนมาจากข้อมูลเทรนยุค 1.x — df.cast(pl.Date), concat แนวนอนที่ความสูงไม่เท่ากัน, is_in ข้ามชนิด — ซึ่งใน 2.0 กลายเป็น error หมด นี่เป็นเรื่องดีในระยะสั้น (พังเสียงดังคือพังที่แก้ได้) แต่เป็นเครื่องเตือนที่ควรจำ: ทุกครั้งที่ไลบรารีขึ้นเวอร์ชันหลัก ช่องว่างระหว่าง “โค้ดที่โมเดลเขียนได้คล่อง” กับ “โค้ดที่ถูกต้องวันนี้” จะกว้างขึ้นทันที และจะแคบลงก็ต่อเมื่อโมเดลรุ่นถัดไปถูกเทรนใหม่ ช่วงระหว่างนั้นคือช่วงที่ context/เอกสารเวอร์ชันใหม่ในพรอมป์ตมีค่ามากกว่าการเปลี่ยนไปใช้โมเดลที่ฉลาดกว่า

คำแนะนำสำหรับทีมไทยที่ใช้ Polars ใน pipeline ข้อมูลจริง: อย่าเพิ่งอัปเกรด production ตอนนี้ — มันคือ RC ไม่ใช่ตัวจริง และตัวจริงจะมาใน “ไม่กี่สัปดาห์” ตามที่ทีมบอกเอง ช่วงนี้ควรใช้ทำสองอย่างแทน หนึ่งคือรันชุดข้อมูลจริงของคุณเทียบผลระหว่าง 1.44 กับ 2.0rc1 แล้วดูว่า ผลต่างกันหรือไม่เมื่อจัดเรียงทั้งสองฝั่งก่อนเปรียบเทียบ ถ้าต่างเฉพาะตอนไม่จัดเรียง แปลว่าคุณมีจุดที่พึ่งลำดับแถวอยู่และรู้แล้วว่าอยู่ตรงไหน สองคือเติมเทสต์ที่ยืนยันลำดับในจุดเหล่านั้นเสียก่อน แล้วค่อยปล่อยให้เอเจนต์ทำงานอัปเกรดที่เหลือ — เพราะเมื่อความคาดหวังถูกเขียนเป็นเทสต์แล้ว มันก็กลับไปเป็น breaking change ประเภทที่พังเสียงดัง ซึ่งเป็นประเภทที่เครื่องช่วยได้

ส่วนประโยชน์ฝั่งบวกก็ของจริงและตรงกับข้อจำกัดของทีมไทยพอดี: ทีมที่ทำงานบนเครื่องเดียวหรือ VM แรมจำกัดแทน cluster — ซึ่งเป็นค่าปกติของทีมข้อมูลไทยส่วนใหญ่ — คือกลุ่มที่ได้ประโยชน์จาก streaming-by-default มากที่สุด เพราะปัญหาที่เจอบ่อยที่สุดไม่ใช่ช้า แต่คือ OOM กลางงาน

แหล่งข่าว

บทความนี้เรียบเรียงจากแหล่งข่าวต้นทาง — Polars

เนื้อหาบน blog นี้สร้างโดย AI โดยมีการกำกับบรรณาธิการจากมนุษย์

อ่านเพิ่มในหมวด เครื่องมือนักพัฒนา

Betelgeuse รัน Qwen3.8 Flash Next ขนาด 68GB บน RTX 3060 กับแรม 16GB ส่วน Basalt วัดให้เห็นว่าเอนจินที่เร่งด้วยแฟล็กลัดทำให้โมเดลลืมของ
เครื่องมือนักพัฒนา

Betelgeuse รัน Qwen3.8 Flash Next ขนาด 68GB บน RTX 3060 กับแรม 16GB ส่วน Basalt วัดให้เห็นว่าเอนจินที่เร่งด้วยแฟล็กลัดทำให้โมเดลลืมของ

Betelgeuse ฟอร์ก llama.cpp ที่เปิดเมื่อ 31 ต.ค. ดึง expert จาก NVMe เข้า VRAM ตามต้องการ อ้าง 22 tok/s แบบไม่ทิ้ง expert แต่ README เตือนเองว่ายังทดลองและตัวเลขมาจากคนละรอบ วันเดียวกันผู้พัฒนา Basalt เผยผลวัดว่าแฟล็กเร่งความเร็วทำคุณภาพ Q8 ตกไปใกล้ Q2

· อ่าน 5 นาที
กฎห้ามโคลนเกมของ Claude Code เริ่มกระทบงานจริง บริษัทรับทำเกมกระดานร้องงานลูกค้าหยุด แต่รายงานหลายชิ้นปนกับตัวกรองไซเบอร์คนละเรื่อง
เครื่องมือนักพัฒนา

กฎห้ามโคลนเกมของ Claude Code เริ่มกระทบงานจริง บริษัทรับทำเกมกระดานร้องงานลูกค้าหยุด แต่รายงานหลายชิ้นปนกับตัวกรองไซเบอร์คนละเรื่อง

ต่อจากที่เราพบกฎนี้ในไบนารี Claude Code ผู้ใช้เริ่มรายงานว่างานเชิงพาณิชย์ถูกปฏิเสธ และ Tom's Hardware กับ Mashable หยิบไปรายงาน แต่เมื่อไล่ issue ที่อ้างถึง พบว่าหลายรายการเกิดก่อนกฎจะมา จึงน่าจะเป็นตัวกรองด้านไซเบอร์ ส่วน Anthropic ยังไม่ชี้แจง

· อ่าน 4 นาที
Claude Code ส่ง transcript ของ background agent ให้โมเดลทุก ~30 วินาทีเพื่อเขียนสถานะ 3–5 คำ ผู้วัดรายงานกินราว 16% และยังปิดแบบทางการไม่ได้
เครื่องมือนักพัฒนา

Claude Code ส่ง transcript ของ background agent ให้โมเดลทุก ~30 วินาทีเพื่อเขียนสถานะ 3–5 คำ ผู้วัดรายงานกินราว 16% และยังปิดแบบทางการไม่ได้

รายงานอิสระพบว่าฟีเจอร์ agent_summary ของ Claude Code ส่ง transcript เต็มของ background agent ไปถามสถานะทุก ~30 วินาที คิดเป็น 16.4% ของค่าใช้จ่ายในระบบของผู้วัด Issue เปิดมาตั้งแต่ ส.ค. ยังไม่มีสวิตช์ปิดที่รองรับ เราตรวจพบโค้ดนี้ใน 2.1.314 และพบกฎใหม่เรื่องเกมที่ไม่อยู่ใน changelog

· อ่าน 4 นาที