บทที่ 1: แกะกล่องและตั้งค่า DGX Spark

← สารบัญคู่มือ

⭐ หลักการข้อแรกของคู่มือเล่มนี้: อย่าใช้เครื่องแบบไร้จอ (headless)

ตั้งเครื่องคู่กับจอ + คีย์บอร์ด + เมาส์เป็นหลัก — หรืออย่างน้อยเก็บชุดนี้ไว้ใกล้เครื่อง พร้อมเสียบได้ทันที

เหตุผลตรงๆ จากประสบการณ์จริงของเรา: การอัปเดตระบบของ NVIDIA เคยทำให้เครื่อง “หายไปจากเครือข่าย” มาแล้ว — driver ที่ต้องรีบูตถึงใช้ได้, ชื่อเครื่องถูกเปลี่ยนอัตโนมัติ, กระทั่ง WiFi ถูกล้างจนเครื่องกลับสู่โหมดแกะกล่อง เหตุการณ์พวกนี้ถ้าเครื่องไร้จอ = เข้าไม่ได้เลยจนกว่าจะหาจอมาต่อ แต่ถ้ามีจออยู่แล้ว = แก้จบในไม่กี่นาทีทุกกรณี

SSH/การเข้าเครื่องระยะไกล (สอนในบทนี้) คือความสะดวกสำหรับงานประจำวัน — ไม่ใช่สิ่งทดแทนจอ

1.1 ของในกล่องและการต่อครั้งแรก

ในกล่อง: ตัวเครื่อง DGX Spark, อะแดปเตอร์ไฟ (USB-C 240W), สาย USB-C — ตัวเครื่องมีพอร์ต USB-C 4 ช่อง, HDMI 2.1a, พอร์ต LAN 10GbE (RJ45), พอร์ต QSFP 200GbE สองช่อง (ไว้ต่อ Spark สองเครื่องเข้าด้วยกัน — cluster), WiFi 7, Bluetooth

ต่อจอ + คีย์บอร์ด + เมาส์ตั้งแต่แรก และวางแผนให้มันอยู่กับเครื่องถาวร (ตามหลักการข้อแรกด้านบน) — ทุกการตั้งค่าเครือข่ายในคู่มือนี้ทำผ่านหน้าจอ Settings ทั้งหมด

การเปิดเครื่องครั้งแรกแบ่งเป็น 2 ช่วง: ช่วง wizard ตั้งค่าบนจอ (ยังไม่มี Terminal ให้ใช้) และช่วงเปิด Terminal ครั้งแรก — เดินตามลำดับทั้งหมด อย่าข้าม

ช่วงที่ 1: Setup wizard — 9 หน้าจอก่อนจะได้เห็น Desktop (ภาพจริงจากเครื่องเรา ส.ค. 2026)

เครื่อง Spark มีหลายยี่ห้อ (ของ NVIDIA เอง, ASUS Ascent GX10, ฯลฯ) — หน้าจอ wizard จะขึ้นชื่อตามยี่ห้อ เช่น “Set Up Your ASUS Ascent GX10” แต่ขั้นตอนเหมือนกันทุกยี่ห้อ เพราะข้างในคือ DGX OS ตัวเดียวกัน ต่างแค่ชื่อเครื่องเริ่มต้น (gx10-xxxx ของ ASUS, spark-xxxx ของ NVIDIA)

เวลาที่ควรเผื่อ: ~20–60 นาที (ส่วนใหญ่หมดไปกับขั้นดาวน์โหลดอัปเดตอัตโนมัติ — ขึ้นกับความเร็วเน็ต)

(ภาพประกอบทั้งหมดวาดขึ้นใหม่จากหน้าจอจริงเพื่อความคมชัด — หน้าตา/ข้อความตรงกับของจริง)

  1. Welcome — “Let’s setup your new personal AI supercomputer” → กด Get Started

หน้า Welcome

  1. Select Language / Timezone — ภาษาเลือก US - English (ยังไม่มีภาษาไทยให้เลือกในนี้ — ไปเพิ่มทีหลังใน Settings ได้), Timezone เลือก Asia - Bangkok → Continue

หน้าเลือกภาษาและ timezone
3. Keyboard Layout — เลือก layout English (US) และ variant English (US) (คีย์บอร์ดไทยค่อยเพิ่มทีหลังเช่นกัน) → Continue
4. Terms Of Use — สัญญาอนุญาตซอฟต์แวร์ของ NVIDIA เลื่อนดูแล้วกด Accept
5. Create a new account for this device — ตั้ง username (แนะนำสั้นๆ ตัวพิมพ์เล็กล้วน) + password → Continue
– นี่คือบัญชีหลัก (sudo) ของเครื่อง — จด username/password ลงใบส่งมอบทันที ลืมแล้วกู้ยากมาก
– ปุ่ม Continue จะเป็นสีเทาจนกว่าจะกรอกครบและรหัสผ่านผ่านเงื่อนไขความซับซ้อน — ถ้ากดไม่ได้ให้ตั้งรหัสให้ยาวขึ้น/ผสมตัวเลข-อักขระพิเศษ แล้วกรอก Confirm ให้ตรงกัน

หน้าสร้างบัญชีหลักของเครื่อง
6. Help NVIDIA Improve Your Experience — ช่องส่ง telemetry ให้ NVIDIA 2 ช่อง (Analytics / Crash data) ระบบติ๊กมาให้แล้วทั้งคู่ — เอาออกได้ถ้าไม่ต้องการส่งข้อมูล ไม่กระทบการใช้งาน → Continue
7. Connect To Wi-Fi — เลือกเครือข่ายจากรายการ ใส่รหัส กด Join
– ⚠️ SSID ชื่อภาษาไทยจะแสดงเป็น ��������� อ่านไม่ออก (ฟอนต์หน้า wizard ยังไม่รองรับ) — ใช้เครือข่ายที่ตั้งชื่อเป็นภาษาอังกฤษ หรือถ้าจำเป็นให้เดาจากลำดับ/ความแรงสัญญาณ
– ขั้นนี้ข้ามไม่ได้ในทางปฏิบัติ เพราะขั้นถัดไปเครื่องต้องใช้เน็ตโหลดอัปเดต

หน้าเลือก WiFi — สังเกตชื่อเครือข่ายภาษาไทยที่แสดงผลไม่ได้
8. Updating Your … — “Downloading and installing system updates” เครื่องโหลด+ติดตั้งอัปเดตระบบอัตโนมัติ มีแถบ progress
– ห้ามปิดเครื่อง/ถอดปลั๊กเด็ดขาด ปล่อยให้วิ่งจนจบ (บน WiFi อาจนานหลายสิบนาที — ปกติ)

หน้าดาวน์โหลดอัปเดตอัตโนมัติ

  1. Almost Done! — “Please wait while your … is rebooted to complete setup” เครื่องรีบูตตัวเอง จะเห็นโลโก้ยี่ห้อ + แถบ progress อีกครั้ง (บางเครื่องมีอัปเดต firmware ช่วงนี้ด้วย — ปกติ ไม่ต้องกดอะไร) → เข้าหน้า login → ใส่รหัสผ่าน → ถึง Desktop ครั้งแรก

หน้า Almost Done ก่อนรีบูตอัตโนมัติ

สิ่งที่จะเห็นหลังถึง Desktop (ของแถมจากระบบ ไม่ใช่ความผิดปกติ):
– Firefox เปิดหน้า build.nvidia.com/spark ให้อัตโนมัติ — รวม quickstart/playbook ของ NVIDIA (Ollama, ComfyUI, DGX Dashboard, vLLM) น่า bookmark เก็บไว้
– เครื่องมี DGX Dashboard เป็น service ในตัวที่ http://localhost:11000 — เวลาระบบแจ้งเตือนว่ามีอัปเดต (OTA) จะพาเข้าหน้านี้เพื่อดู Available Updates (การกดอัปเดตจากหน้านี้ = อัปเดตใหญ่ ควรอ่านหัวข้อ 1.10 ก่อน)

ช่วงที่ 2: เปิด Terminal ครั้งแรก (5 ขั้น — ขั้น 2–4 คือหัวใจ อย่าข้าม)

เครื่องเข้าสู่ DGX OS (Ubuntu ปรับแต่งโดย NVIDIA มาพร้อม driver/CUDA ครบ ไม่ต้องลงเอง) และต่อ WiFi แล้วจากช่วงที่ 1 (อยากเสียบสาย LAN เพิ่มก็ทำได้ที่ Settings → Network)

  1. เปิด Terminal — จดชื่อเครื่องก่อน (hostname — รูปแบบ spark-xxxx หรือ gx10-xxxx ตามยี่ห้อ) แล้วอัปเดตระบบ:
sudo apt update && sudo apt full-upgrade -y
sudo apt install -y build-essential cmake git curl tmux htop rsync libcurl4-openssl-dev

(สองแพ็กเกจแรกสำคัญมากบนเครื่อง ARM — จะต้อง compile ของเองบ่อย และเครื่องเปล่าไม่มี gcc ซึ่งทำให้บาง engine พังแบบงงๆ เราเจอมาแล้ว — wizard เพิ่งอัปเดตให้รอบหนึ่งก็จริง แต่รอบนั้นเป็นอัปเดตของระบบ ไม่ได้ลงเครื่องมือ dev พวกนี้ให้)

  1. จด IP ของเครื่องตอนนี้เลย (อย่ารอ): หน้า Settings → Wi-Fi → กด ⚙ ข้างเครือข่ายที่ต่ออยู่ → จดค่า IPv4 Address (ถ้าต่อสาย LAN: Settings → Network → ⚙ เช่นกัน) — หรือพิมพ์ใน Terminal:
ip -br addr | grep -E 'wl|en'    # บรรทัด wl... = WiFi, en... = สาย LAN — จด IP ไว้
  1. ทดสอบ ssh จากโน้ตบุ๊กทันที (ตอนนี้จอยังต่ออยู่ พลาดอะไรก็แก้ได้เลย): เปิด Terminal บนโน้ตบุ๊กที่ต่อเครือข่ายเดียวกัน:
ssh <user>@<IP ที่จดจากขั้น 2>

เข้าได้ = remote access ใช้งานได้จริง ✓

  1. สั่งรีบูตผ่าน ssh นั้นเลย:
sudo reboot

ขั้นนี้บังคับ ไม่ใช่ทางเลือก — full-upgrade เพิ่งอัปเดต NVIDIA driver การรีบูตทำให้ kernel โหลดโมดูลตัวใหม่ให้ตรงกัน (ถ้าข้ามขั้นนี้ nvidia-smi จะพัง — ดูหัวข้อ 1.10 Troubleshooting) และการรีบูตผ่าน ssh ก็คือการซ้อมใช้งานจริงครั้งแรกไปในตัว — รอ ~1 นาทีแล้ว ssh กลับเข้าไปใหม่ได้เลย

  1. หลังรีบูต ~1 นาที ssh กลับเข้าไปใหม่ แล้วเช็คสุขภาพเครื่อง — คำสั่งชุดนี้ควรรันได้ทุกตัวก่อนไปต่อ:
uname -m        # ต้องได้ aarch64
nvidia-smi      # เห็น GPU GB10 + CUDA version (ถ้าพังตรงนี้ = ยังไม่ได้รีบูตหลังอัปเกรด)
free -h         # เห็น memory ~120GB
df -h /         # ดิสก์เหลือเท่าไหร่ (รุ่น 4TB ควรว่าง ~3.6T)
hostname        # ยืนยันชื่อเครื่องอีกรอบ (อัปเกรดใหญ่อาจเปลี่ยนชื่อ — ดู 1.10)

ครบทุกข้อ = เครื่องพร้อม, remote access พร้อม, IP อยู่ในมือ — จบพิธีเปิดกล่องอย่างสมบูรณ์

อ่านผล nvidia-smi ให้เป็น (หน้าตาบน Spark ไม่เหมือนการ์ดจอทั่วไป)

ตัวอย่าง output จริงจากเครื่องเรา พร้อมจุดที่ต้องดู:

+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.173.02             Driver Version: 580.173.02     CUDA Version: 13.0     |
+-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GB10                    On  |   0000000F:01:00.0  On |                  N/A |
| N/A   48C    P8              4W /  N/A  | Not Supported          |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|    0   N/A  N/A            7243      G   /usr/lib/xorg/Xorg                       67MiB |
|    0   N/A  N/A            7394      G   /usr/bin/gnome-shell                    143MiB |
+-----------------------------------------------------------------------------------------+
จุด อ่านว่า ค่าปกติ
① Driver Version เวอร์ชัน driver — สองตำแหน่งนี้ต้องตรงกัน (ถ้าเพี้ยนจะขึ้น error mismatch → ดู 1.10) ตัวเลขชุดเดียวกัน
② CUDA Version รุ่น CUDA ของเครื่อง 13.0 ขึ้นไป
③ Name ชื่อ GPU อยู่ตรงนี้ — ในตาราง ไม่ใช่หัวกระดาษ: NVIDIA GB10 ต้องเห็น GB10
④ Temp อุณหภูมิ GPU ว่าง ~40–50C, งานหนัก 70–85C
⑤ Perf state ระดับพลังงาน: P8 = พักผ่อน, P0 = ทำงานเต็มที่ เปลี่ยนตามโหลด
⑥ Power กำลังไฟที่ใช้ตอนนี้ (/N/A = ไม่แสดงเพดาน — ปกติบนเครื่องนี้) ว่าง ~4W, เต็มสูบหลายสิบ W
⑦ Memory-Usage = Not Supported ไม่ใช่เครื่องเสีย! GB10 ใช้ unified memory — ไม่มี VRAM แยกให้รายงาน ดูหน่วยความจำจาก free -h แทนเสมอ
⑧ GPU-Util เปอร์เซ็นต์การใช้งาน GPU 0% ตอนว่าง / 90–100% ตอนโมเดลคิด

ส่วนตาราง Processes ข้างล่าง: เห็น Xorg กับ gnome-shell กินไม่กี่ร้อย MiB เป็นเรื่องปกติ (หน้าจอ GUI ใช้ GPU วาดภาพ) — เวลารันโมเดลจะเห็น process ของ engine โผล่เพิ่มพร้อมตัวเลขหน่วยความจำก้อนใหญ่

สรุปวิธีเช็คเร็ว: เห็นตาราง = driver ปกติ / เห็น GB10 = เครื่องถูกตัว / Not Supported ตรง Memory = เรื่องปกติของ Spark อย่าตกใจ

อ่านผล free -h ให้เป็น (นี่แหละ “มิเตอร์ VRAM” ของ Spark)

เพราะ Spark ใช้ unified memory — หน่วยความจำก้อนเดียวเป็นทั้ง RAM และ VRAM — คำสั่งนี้จึงเป็นมิเตอร์หลักที่ต้องอ่านเป็นก่อนโหลดโมเดลทุกครั้ง เทียบ output จริงจากเครื่องเราสองสถานะ:

เครื่องเพิ่งเปิด ยังไม่โหลดอะไร:

               total        used        free      shared  buff/cache   available
Mem:           121Gi        11Gi       114Gi        13Mi       2.7Gi       110Gi
Swap:           15Gi          0B        15Gi

เครื่องเดียวกันขณะมีโมเดลโหลดอยู่ + ใช้งานมาทั้งวัน:

               total        used        free      shared  buff/cache   available
Mem:           121Gi        48Gi        29Gi        33Mi        53Gi        73Gi
Swap:           80Gi        13Mi        80Gi

สังเกตความต่าง: used โต 11→48Gi (โมเดลเข้ามาอยู่) และ buff/cache โต 2.7→53Gi (ใช้เครื่องไปเรื่อยๆ Linux ยืมที่ว่างเก็บ cache ไฟล์มากขึ้นเอง — ปกติ) แต่ available คือตัวที่บอกความจริงทั้งสองสถานะ

คอลัมน์ อ่านว่า ตัวอย่างข้างบน
total หน่วยความจำทั้งหมด (128GB เครื่องจะโชว์ ~121Gi หลังหักส่วนระบบ) 121Gi
used ที่ถูกใช้จริงตอนนี้ — โมเดลที่โหลดอยู่โผล่ตรงนี้ 48Gi (มีโมเดลอยู่ตัวหนึ่ง)
free ที่ว่างเปล่าจริงๆ — ตัวเลขนี้หลอก! อย่าใช้ตัดสิน 29Gi
buff/cache Linux ยืมที่ว่างมาเก็บ cache ไฟล์ — คืนให้ทันทีเมื่อโปรแกรมต้องการ 53Gi
available ★ ตัวเลขเดียวที่ควรดู = free + cache ที่คืนได้ ≈ ที่เหลือให้โมเดลตัวถัดไปจริงๆ 73Gi
แถว Swap หน่วยความจำสำรองบนดิสก์ (ช้ามาก) — ค่า used ควรเกือบศูนย์เสมอ 13Mi ✓

สองกฎที่ใช้ทุกวัน:

  1. จะโหลดโมเดลเพิ่ม → ดู available ไม่ใช่ free — มือใหม่เห็น free 29Gi แล้วคิดว่าโหลดโมเดล 40GB ไม่ได้ ทั้งที่จริง available มี 73Gi (cache จะหลบให้เอง) — นี่คือพฤติกรรมปกติของ Linux: ความจำว่างจะถูกยืมไปทำ cache เสมอ “free ต่ำ” ไม่ใช่ปัญหา
  2. Swap used พุ่งเป็น GB ขณะรันโมเดล = สัญญาณอันตราย — แปลว่ายัดเกินเครื่องแล้ว ระบบกำลังหน่วงหนัก (ทุกอย่างช้าลง 10–100 เท่า) → ปิดโมเดลบางตัวหรือใช้ quant เล็กลง

ดูสด ๆ ระหว่างโหลดโมเดล: watch -n 2 free -h — จะเห็น used ค่อยๆ บวมขึ้นตามโมเดลที่กำลังโหลด สนุกดีและได้ intuition เร็วมาก

ปรับ swap ให้พอสำหรับงานโมเดลใหญ่ (ทำครั้งเดียว — แนะนำทำเลยตอน setup)

ค่าจากโรงงานให้ swap มาแค่ ~15GB ซึ่งเล็กเกินไปสำหรับเครื่องที่จะโหลดโมเดลระดับ 50–100GB: จังหวะที่โมเดลใหญ่กำลังโหลด/สลับตัว หน่วยความจำจะตึงชั่วขณะและระบบต้องการที่ระบาย — swap เล็กทำให้เคลียร์ cache ไม่ทัน อาการคือเครื่องอืดหนัก ค้าง หรือโปรแกรมโดนฆ่ากลางทาง (OOM) ทั้งที่ความจริงแค่ต้องการพื้นที่หายใจชั่วคราว

แนะนำ: เพิ่ม swapfile อีก ~64GB (วิธีเดียวกับเครื่องเราจริงๆ — เพิ่มไฟล์ใหม่ ไม่แตะของเดิม ปลอดภัยและถอนง่าย) — ดิสก์หายไป 64GB แลกกับความนิ่ง คุ้มมาก:

sudo fallocate -l 64G /swapfile-models     # สร้างไฟล์ 64GB
sudo chmod 600 /swapfile-models            # จำกัดสิทธิ์ (จำเป็น)
sudo mkswap /swapfile-models               # ฟอร์แมตเป็น swap
sudo swapon /swapfile-models               # เปิดใช้ทันที
echo '/swapfile-models none swap sw 0 0' | sudo tee -a /etc/fstab   # ให้รอดรีบูต

swapon --show                              # ตรวจ: ต้องเห็น 2 บรรทัด (ของเดิม + ตัวใหม่ 64G)
free -h                                    # แถว Swap รวมควรเป็น ~79Gi

ความเข้าใจที่ถูกต้องเรื่อง swap ใหญ่: มันคือเข็มขัดนิรภัย ไม่ใช่ RAM เพิ่ม — การใช้งานปกติค่า Swap used ควรใกล้ศูนย์เหมือนเดิม (ตามกฎในหัวข้อ free -h) ประโยชน์ของมันคือรับแรงกระแทกชั่วคราวตอนโหลด/สลับโมเดลไม่ให้ระบบล้ม ถ้าเห็น swap ถูกใช้หลาย GB ค้างตลอดเวลาที่โมเดลรัน = ยัดเกินเครื่องจริง ต้องลดขนาดโมเดลอยู่ดี

(ถอนคืนถ้าต้องการ: sudo swapoff /swapfile-models && sudo rm /swapfile-models แล้วลบบรรทัดใน /etc/fstab)

อ่านผล df -h ให้เป็น (ดิสก์ — ทรัพยากรที่โมเดลกินเร็วที่สุด)

output จริงจากเครื่องเรา (รุ่นดิสก์ 1TB) — มือใหม่เห็นครั้งแรกมักตกใจว่าทำไมบรรทัดเยอะจัง:

Filesystem      Size  Used Avail Use% Mounted on
tmpfs            13G  2.8M   13G   1% /run                      ← ไม่ใช่ดิสก์ (RAM จำลอง) — ข้าม
efivarfs        256K   37K  220K  15% /sys/firmware/efi/efivars ← ระบบ boot — ห้ามยุ่ง
/dev/nvme0n1p2  916G  405G  464G  47% /                         ← ★ ดิสก์จริงของเรา — ดูบรรทัดนี้บรรทัดเดียว
tmpfs            61G     0   61G   0% /dev/shm                  ← RAM จำลอง — ข้าม
tmpfs           5.0M  8.0K  5.0M   1% /run/lock                 ← ข้าม
/dev/nvme0n1p1  511M  6.4M  505M   2% /boot/efi                 ← ระบบ boot — ห้ามยุ่ง
tmpfs            13G  124K   13G   1% /run/user/1000            ← ข้าม

กติกาการอ่าน:

  1. สนใจบรรทัดเดียว: บรรทัดที่ Mounted on เป็น / (ชื่อ Filesystem จะเป็น /dev/nvme...) — นั่นคือ SSD จริงของเครื่อง อ่านสามค่า: Size (ความจุรุ่นเครื่อง เช่น 916G = รุ่น 1TB, ~3.6T = รุ่น 4TB), Avail (เหลือใช้จริง), Use% (ใช้ไปกี่เปอร์เซ็นต์)
  2. บรรทัด tmpfs ทั้งหลาย = พื้นที่จำลองใน RAM ที่ระบบใช้ภายใน — ไม่ใช่ดิสก์ ไม่ต้องอ่าน / efivarfs กับ /boot/efi = ส่วนของระบบ boot — รู้ว่ามีอยู่ก็พอ
  3. ทางลัดตัดความรก: df -h / — แสดงเฉพาะบรรทัดที่สำคัญบรรทัดเดียวจบ (คู่มือนี้ใช้แบบนี้ตลอด)

ทำไมต้องดูบ่อย: โมเดลกินดิสก์เร็วกว่าที่คิดมาก — DeepSeek 2-bit ตัวเดียว ~80GB, Qwen3.6 ~20GB, ยังไม่รวม docker image และ cache ที่งอกเงียบๆ เครื่องรุ่น 1TB โหลดโมเดลใหญ่ 3–4 ตัวก็ตึงแล้ว กฎที่ใช้: เช็ค Avail ก่อนดาวน์โหลดทุกครั้ง (ไฟล์ที่จะโหลด + เผื่อ 20%) และอย่าปล่อยให้ Use% เกิน ~90% — ดิสก์เต็มทำให้ทุกอย่างพังแบบงงๆ (ดาวน์โหลดค้าง, โมเดลเซฟไม่ได้, ระบบอืด)

เมื่อดิสก์ใกล้เต็มแล้วหาไม่เจอว่าอะไรกิน:

du -xh --max-depth=1 ~ | sort -rh | head    # ไล่ดูว่าโฟลเดอร์ไหนในบ้านเรากินเท่าไหร่ เรียงจากใหญ่สุด

ผู้ต้องสงสัยประจำ: ~/models/, ~/.cache/huggingface/ (cache ดาวน์โหลดที่มักถูกลืม), และ docker images (docker system df)

1.2 เข้าเครื่องจากคอมตัวเอง: SSH + mDNS

หลังต่อเน็ตแล้ว เครื่องจะประกาศชื่อตัวเองในวง LAN ผ่าน mDNS — จากเครื่อง Mac/Linux ในบ้านเดียวกัน:

ssh <user>@spark-xxxx.local

ใช้ชื่อ .local เสมอ อย่าจำ IP — IP เป็น DHCP และเปลี่ยนได้ (เราโดนมาแล้ว: IP เปลี่ยนแล้ว config ที่ fix IP ไว้พังเป็นแถบ) ถ้าอยากจบปัญหาถาวรให้ตั้ง DHCP reservation ที่ router

ติด SSH key จะได้ไม่ต้องพิมพ์รหัสทุกครั้ง:

ssh-copy-id <user>@spark-xxxx.local

กฎเหล็กข้อแรกของการทำงานผ่าน SSH: งานยาวต้องรันใน tmux เสมอ — สำคัญจนแยกเป็นหัวข้อของตัวเองในข้อถัดไป

1.3 tmux — เครื่องมือบังคับเมื่อทำงานผ่าน SSH (อ่านให้จบก่อนรันงานยาวครั้งแรก)

ทำไมถึง “บังคับ” ไม่ใช่ “แนะนำ”

เวลา ssh เข้าเครื่อง โปรแกรมทุกตัวที่รันจะผูกชีวิตติดกับ session ssh นั้น — WiFi กระตุกสองวินาที, ปิดฝาโน้ตบุ๊ก, sleep — ssh หลุดเมื่อไหร่ งานที่รันอยู่ตายทันที ลองนึกภาพ: ดาวน์โหลดโมเดล 80GB มาแล้ว 5 ชั่วโมง เหลืออีก 10 นาที แล้วแมวเดินเหยียบ router… บนเครื่องที่ต่อ WiFi แบบ Spark เรื่องแบบนี้ไม่ใช่ “ถ้า” แต่คือ “เมื่อไหร่”

tmux แก้เรื่องนี้ด้วยแนวคิดเดียว: จอทำงานของเราอยู่บนเครื่อง Spark ไม่ใช่บนเครื่องที่ ssh มา — ssh เป็นแค่ “หน้าต่างแอบดู” จอนั้น หลุดแล้วจอจริงยังอยู่ งานยังวิ่ง กลับมาเปิดหน้าต่างดูใหม่เมื่อไหร่ก็ได้

คำถามแรกของมือใหม่: แล้วพิมพ์คำสั่ง tmux ที่ไหน — ต้อง ssh ก่อนไหม?

ต้อง ssh ก่อนเสมอ — tmux เป็นโปรแกรมที่รันบนเครื่อง Spark ไม่ใช่บนโน้ตบุ๊กเรา ลำดับที่ถูกคือ:

[โน้ตบุ๊กเรา]                         [เครื่อง Spark]
เปิด Terminal
  └─ ssh user@spark-xxxx.local ──────→ ได้ shell ของ Spark
                                        (สังเกต prompt เปลี่ยนเป็น user@spark-xxxx)
                                          └─ พิมพ์ tmux new -s dl   ← พิมพ์ตรงนี้!
                                               └─ รันงานยาวในนั้น
                                          └─ Ctrl+b, d (detach)
  └─ ปิดโน้ตบุ๊กได้เลย ✓                      งานยังวิ่งต่อบน Spark ✓

--- วันถัดมา ---
เปิด Terminal ใหม่
  └─ ssh user@spark-xxxx.local ──────→ (ssh รอบใหม่ คนละอันกับเมื่อวาน — ไม่เป็นไร)
                                          └─ tmux attach -t dl  → งานเดิมอยู่ครบ

วิธีเช็คง่ายๆ ว่ากำลังพิมพ์อยู่ฝั่งไหน: ดู prompt — ถ้าขึ้น user@spark-xxxx:~$ คืออยู่บน Spark (พิมพ์ tmux ได้) ถ้าเป็นชื่อเครื่องตัวเองคือยังไม่ได้ ssh — และจำง่ายๆ ว่า ssh คือประตู, tmux คือโต๊ะทำงานหลังประตูนั้น ประตูปิด (ssh หลุด) โต๊ะไม่หาย เปิดประตูใหม่ก็เจอโต๊ะเดิม

ศัพท์ 3 คำที่ต้องรู้

  • Session = โต๊ะทำงานหนึ่งตัว มีชื่อเรียก (เช่น dl, train) — อยู่ถาวรจนกว่าจะสั่งปิดหรือรีบูตเครื่อง
  • Window = แท็บบนโต๊ะนั้น (เหมือนแท็บ browser) — หนึ่ง session มีได้หลาย window
  • Attach / Detach = เปิดหน้าต่างเข้าไปดูโต๊ะ / ถอยออกมาโดยโต๊ะยังอยู่

ชุดคำสั่งที่ใช้จริง 90% ของเวลา

tmux new -s dl          # เปิดโต๊ะใหม่ชื่อ "dl" (แล้วเข้าไปอยู่ในนั้นเลย)
# ... สั่งดาวน์โหลด/เทรน/build อะไรก็ว่าไป ...

# ออกจากโต๊ะโดยงานยังวิ่งต่อ (detach):
#   กด  Ctrl+b  แล้วปล่อย  แล้วกด  d

tmux ls                 # อยู่ข้างนอก: ดูว่ามีโต๊ะอะไรเปิดอยู่บ้าง
tmux attach -t dl       # กลับเข้าโต๊ะ "dl" — เห็นทุกอย่างที่เกิดขึ้นระหว่างเราไม่อยู่
tmux kill-session -t dl # ปิดโต๊ะเมื่องานจบแล้วจริงๆ

เรื่องปุ่ม Ctrl+b (เรียกว่า prefix): ทุกคำสั่งคีย์บอร์ดของ tmux เริ่มด้วยการกด Ctrl+b ปล่อยก่อน แล้วค่อยกดตัวอักษรคำสั่ง — มันคือการบอกว่า “ปุ่มถัดไปคุยกับ tmux นะ ไม่ใช่กับโปรแกรมในจอ”

สถานการณ์จริง 3 แบบ

แบบที่ 1 — ดาวน์โหลดโมเดลข้ามคืน:

tmux new -s dl
HF_HUB_DISABLE_XET=1 hf download unsloth/DeepSeek-V4-Flash-0731-GGUF --include "*UD-IQ2_M*" --local-dir ~/models/gguf/deepseek-0731/
# กด Ctrl+b, d → ปิดโน้ตบุ๊กไปนอนได้เลย
# ตื่นเช้า: ssh เข้ามา → tmux attach -t dl → เห็นผลลัพธ์

แบบที่ 2 — รัน server ทดลองก่อนทำเป็น systemd:

tmux new -s llm
~/llama.cpp/build/bin/llama-server -m ~/models/gguf/... --port 8080 ...
# Ctrl+b, d → server รันต่อ ทดสอบยิง API จากเครื่องอื่นได้
# อยากดู log สด: attach กลับเข้าไป

(server ที่ใช้ประจำควร “จบการทดลอง” ด้วยการย้ายไป systemd — tmux คือสนามซ้อม ไม่ใช่บ้านถาวร เพราะไม่รอดรีบูต)

แบบที่ 3 — งานเทรนที่อยากเหลือบดูเป็นระยะ:

tmux new -s train
python train.py 2>&1 | tee train.log      # tee = เห็นบนจอด้วย เก็บลงไฟล์ด้วย
# Ctrl+b, d → ระหว่างวัน ssh มา attach ดู loss แล้ว detach ออกกี่รอบก็ได้

การเลื่อนดูข้อความเก่า (จุดที่มือใหม่งงที่สุด)

ใน tmux การ scroll ด้วยเมาส์/trackpad ตรงๆ มักไม่ทำงาน — ต้องเข้า copy mode: กด Ctrl+b แล้วกด [ จากนั้นเลื่อนด้วยลูกศร/PageUp หรือพิมพ์ ? เพื่อค้นหาย้อนหลัง เสร็จแล้วกด q ออก — หรือถ้าชอบใช้เมาส์: tmux set -g mouse on (พิมพ์ครั้งเดียวใน session, scroll ได้เลย)

ตาราง cheat sheet ติดโต๊ะ

อยากทำอะไร คำสั่ง/ปุ่ม
เปิดโต๊ะใหม่ชื่อ X tmux new -s X
ออกโดยงานวิ่งต่อ Ctrl+b แล้ว d
ดูรายชื่อโต๊ะ tmux ls
กลับเข้าโต๊ะ X tmux attach -t X
เปิดแท็บใหม่ในโต๊ะ Ctrl+b แล้ว c
สลับแท็บ Ctrl+b แล้ว n (next) / ตัวเลข
แบ่งจอซ้ายขวา Ctrl+b แล้ว % (บนล่าง: ")
ย้าย pane Ctrl+b แล้วลูกศร
เลื่อนดูของเก่า Ctrl+b แล้ว [ (ออก: q)
ปิดโต๊ะทิ้ง tmux kill-session -t X

ข้อผิดพลาดยอดฮิต

  1. ลืมว่าตัวเองอยู่ใน tmux แล้วเปิด tmux ซ้อน — สังเกตแถบสีเขียวขอบล่างจอ: มีแถบ = อยู่ใน tmux แล้ว อย่า tmux new ซ้ำ
  2. พิมพ์ exit เพื่อจะ detach — exit คือปิดโต๊ะทิ้ง (งานตาย!) — ถ้าจะออกเฉยๆ ต้อง Ctrl+b, d เท่านั้น
  3. เก็บ server ถาวรไว้ใน tmux — รีบูตเมื่อไหร่หายหมดแบบเงียบๆ (เราเคยเจอ demo หายหลังรีบูตเพราะเรื่องนี้) — ใช้ประจำ = systemd
  4. ตั้งชื่อ session มั่ว — ตั้งชื่อตามงาน (dl, train, llm) แล้วจะขอบคุณตัวเองตอน tmux ls เจอ 5 sessions

1.4 ย้ายเครื่อง/เข้าเครื่องไม่ได้: ต่อจอแล้วตั้ง WiFi — จบทุกกรณี

หลักการของหัวข้อนี้: เครื่องที่ส่งมอบถูกตั้งโปรไฟล์ WiFi เริ่มต้น ไว้แล้ว (SSID และรหัสผ่านอยู่ในใบส่งมอบ/หน้าแรกของคู่มือเล่มนี้) — โปรไฟล์นี้คือกุญแจสำรองของเครื่อง: ไม่ว่าหอบเครื่องไปที่ไหน เราเรียกมันกลับมาหาเราได้เสมอ ห้ามลบหรือแก้โปรไฟล์นี้เด็ดขาด และคู่มือนี้จงใจไม่สอนคำสั่งแก้ไข WiFi ของเครื่อง — เพื่อไม่ให้กุญแจสำรองดอกนี้ถูกทำหายโดยไม่ตั้งใจ

สถานการณ์: ย้ายเครื่องไปบ้านใหม่/ออฟฟิศ/หน้างานลูกค้า → เครื่องไม่รู้จัก WiFi ที่นั่น → เปิดมาก็หายเงียบ เข้าไม่ได้

วิธีแก้หลัก (ง่ายสุด ทำเองได้เสมอ): ต่อจอ + คีย์บอร์ด + เมาส์

  1. เสียบจอ (HDMI), คีย์บอร์ด, เมาส์ เข้าเครื่อง Spark
  2. ต่อ WiFi ของสถานที่ใหม่ผ่านหน้า Settings → Wi-Fi ตามปกติ (การเพิ่มเครือข่ายใหม่ไม่กระทบโปรไฟล์เริ่มต้น)
  3. ดู IP WiFi ของเครื่อง: Settings → Wi-Fi → กดไอคอน ⚙ ข้างชื่อเครือข่ายที่ต่ออยู่ → ดูค่า IPv4 Address (หรือเปิด Terminal พิมพ์ ip -br addr แล้วดูบรรทัด wl... ตามหัวข้อ “ทักษะเอาตัวรอด” ข้างล่าง)
  4. กลับไปที่โน้ตบุ๊ก (ต่อ WiFi วงเดียวกัน) → ssh <user>@<IP ที่จดมา> — ใช้งานต่อได้เลย

ทางเลือกเมื่อไม่มีจอติดตัว: เปิด Personal Hotspot บนมือถือ ตั้งชื่อ+รหัสให้ตรงกับ WiFi เริ่มต้นในใบส่งมอบเป๊ะๆ → เครื่องต่อเข้ามาเอง → ดู IP จากหน้าจอ hotspot ของมือถือ → ssh ด้วย IP นั้น / หรือเสียบสาย LAN (RJ45) จาก router ก็ได้ IP ทันทีเช่นกัน

(ถ้าตั้ง Tailscale ไว้ตามหัวข้อ 1.5 — ขั้นที่ 3–4 ยิ่งง่าย: พอเครื่องออกเน็ตได้ผ่าน hotspot ก็ ssh ด้วยชื่อ ts.net ได้ทันที ไม่ต้องหา IP ด้วยซ้ำ)

หมายเหตุสำหรับทีมส่งมอบ (ภายใน): ก่อนส่งทุกเครื่อง — ตั้งโปรไฟล์ WiFi เริ่มต้น + ทดสอบว่าเครื่อง auto-join hotspot ชื่อนั้นจริง + จด SSID/รหัสลงใบส่งมอบ

ทักษะเอาตัวรอด: ดู IP ของเครื่องให้เป็น

เมื่อชื่อ .local ใช้ไม่ได้ (ซึ่งจะเกิดสักวัน) เส้นทางสำรองคือ ssh ด้วย IP ตรงๆ — แต่ต้องรู้ว่า IP ไหนคือ “IP WiFi” เพราะเครื่อง Spark มีหลาย interface และหลาย IP พร้อมกัน:

ip -br addr
lo               UNKNOWN  127.0.0.1/8            ← ตัวเครื่องเอง (ไม่ใช้)
enp1s0f1np1      UP       192.168.100.1/24       ← สาย cluster (ถ้ามี)
wlP9s9           UP       192.168.0.156/24       ← ★ WiFi — ตัวนี้แหละที่ใช้ ssh
docker0          UP       172.17.0.1/16          ← เครือข่ายภายใน docker (ไม่ใช้)

วิธีอ่าน: มองหาบรรทัดที่ชื่อ interface ขึ้นต้นด้วย wl (wireless) — IP ในบรรทัดนั้นคือ IP WiFi / ระวังคำสั่ง hostname -I ที่หลายคนชอบใช้: มันพ่นทุก IP รวมกันไม่บอกว่าอันไหนเป็นอะไร มือใหม่มักคว้า IP ผิดตัว (เช่น 172.17.x.x ของ docker) ไป ssh แล้วงงว่าทำไมไม่ติด

เกร็ดจากเหตุการณ์จริงของเรา: บางครั้ง .local เหมือนพัง แต่จริงๆ คือเครื่องหลายเครือข่ายประกาศ IP ผิดวงออกไป (mDNS ตอบ IP ของสาย cluster ที่โน้ตบุ๊กเราไปไม่ถึง) — วิธีเช็คจากฝั่งโน้ตบุ๊ก: ping spark-xxxx.local ดูว่า IP ที่ตอบมาตรงกับ IP WiFi ของเครื่องไหม ถ้าไม่ตรง ให้ ssh ด้วย IP WiFi ตรงๆ ไปก่อน แล้วแก้ที่ config avahi (deny-interfaces ตัด interface ที่ไม่ใช่ WiFi ออก)

คำเตือนจากประสบการณ์จริง: อย่าแก้ network config ทิ้งไว้แบบไม่ทดสอบ — mDNS/WiFi ที่ทำงานอยู่คือเส้นเลือดเดียวของเครื่อง headless พังแล้วต้องหอบจอไปต่อสถานเดียว และถ้าใช้ WiFi เป็นเน็ตหลัก: การโหลดไฟล์ใหญ่ให้จำกัดจำนวน connection (เช่นใช้ aria2c -x4 แทนการเปิดหลาย connection พร้อมกัน) เพราะ WiFi อิ่มแล้วทั้งเครื่องจะช้าจนเหมือนค้าง

1.5 เข้าเครื่องจากนอกบ้าน: Tailscale

ทุกวิธีที่ผ่านมา (.local, VNC) มีข้อจำกัดเดียวกัน: ใช้ได้เฉพาะเมื่ออยู่ในเครือข่ายเดียวกับเครื่อง — ออกไปร้านกาแฟ ไปออฟฟิศ อยู่ต่างจังหวัด = เข้าเครื่องไม่ได้ วิธีแก้แบบเก่า (forward port ที่ router, fix IP) ทั้งยุ่งและเสี่ยงเปิดเครื่องให้ทั้งอินเทอร์เน็ตเห็น

Tailscale คือทางที่เราใช้จริง: มันสร้าง “เครือข่ายส่วนตัว” เชื่อมอุปกรณ์ทุกตัวของเรา (Spark, โน้ตบุ๊ก, มือถือ) ถึงกันโดยตรงแบบเข้ารหัส ไม่ว่าแต่ละตัวอยู่ที่ไหนในโลก — ไม่ต้องตั้งค่า router, เครื่องอยู่หลัง NAT/WiFi หอพักก็ถึงกัน, และคนนอกมองไม่เห็นอะไรเลย (ฟรีสำหรับใช้ส่วนตัว)

# บนเครื่อง Spark (มี ARM64 build อย่างเป็นทางการ):
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up          # จะให้ลิงก์ไป login (บัญชี Google/GitHub/MS ก็ได้)
tailscale status           # เห็นชื่อ+IP ของเครื่องในเครือข่ายเรา

แล้วลงแอป Tailscale บนโน้ตบุ๊ก/มือถือ ล็อกอินบัญชีเดียวกัน — เท่านี้จากที่ไหนก็ได้:

ssh <user>@spark-xxxx.tailXXXX.ts.net   # ชื่อ MagicDNS ถาวร (ดูจาก tailscale status)
# หรือใช้ IP 100.x.x.x ที่ Tailscale แจก — ไม่เปลี่ยนตาม DHCP!

จุดที่มีประโยชน์เกิน ssh: ทุก service บนเครื่องใช้ผ่านชื่อนี้ได้หมด — Web UI ของโมเดล, API endpoint, VNC — เช่นเราเปิดหน้า ComfyUI จากนอกบ้านด้วย http://spark-xxxx.tailXXXX.ts.net:8188 เป็นประจำ และเพราะเป็นเครือข่ายปิด ไม่ต้องกังวลว่า endpoint ที่ไม่มีรหัสผ่านจะโดนคนแปลกหน้าเจอ

เคล็ดสำหรับเครื่อง server แบบ Spark: ไปที่ admin console (เว็บของ Tailscale) → เครื่อง Spark → Disable key expiry — ไม่งั้นทุก ~6 เดือน key หมดอายุแล้วต้องมา login ใหม่ (ถ้าลืมตอนอยู่ไกลเครื่องคือจบ)

1.6 GUI ระยะไกล (VNC) — สำหรับคนที่อยากเห็นหน้าจอ

DGX OS มี GNOME desktop เต็มรูปแบบ ใช้ผ่าน VNC ได้:

sudo apt install -y tigervnc-standalone-server
vncpasswd                                        # ตั้งรหัส VNC
# รัน VNC บนจอจริง (display :1) ให้เข้าถึงจาก LAN:
x0vncserver -display :1 -rfbport 5900 -PasswordFile=~/.vnc/passwd -SecurityTypes VncAuth -AlwaysShared &

จากเครื่องอื่นใช้ VNC client (บน Mac: Finder → Cmd+K → vnc://spark-xxxx.local:5900)

ความจริงจากการใช้งาน: ~95% ของงานทำผ่าน SSH สะดวกกว่า GUI มีไว้กรณีเฉพาะ (ดู browser ในเครื่อง, app มี UI) — ถ้าไม่ใช้เลยก็ไม่ต้องตั้ง

1.7 Docker + NVIDIA runtime (ทำครั้งเดียว ใช้ตลอด)

หลาย engine/เครื่องมือมาเป็น container การให้ container เห็น GPU ต้องลงทะเบียน NVIDIA runtime ก่อน — เครื่องใหม่ยังไม่ได้ตั้งค่านี้ (เราก็เจอตอน compose ตัวแรก: unknown or invalid runtime name: nvidia):

sudo usermod -aG docker $USER        # ให้ user ใช้ docker ได้ (logout/login ใหม่)
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker        # ⚠️ container ที่รันอยู่จะ restart ด้วย
# ทดสอบ:
docker run --rm --runtime=nvidia nvcr.io/nvidia/cuda:13.0.0-base-ubuntu24.04 nvidia-smi

1.8 กฎเหล็กของเครื่อง ARM (aarch64) — อ่านก่อนติดตั้งทุกอย่าง

นี่คือจุดที่ผู้ใช้ใหม่เจ็บบ่อยที่สุด สรุปจากแผลจริงของเรา:

  1. Binary/wheel ที่ compile สำหรับ x86 ใช้ไม่ได้เด็ดขาด — ก่อนลงอะไรถามเสมอว่า “มี ARM64 build ไหม” ถ้าไม่มีต้อง compile จาก source
  2. PyTorch ต้องเป็นรุ่น CUDA 13 aarch64 — ใช้ container ของ NVIDIA (nvcr.io/nvidia/pytorch) หรือ wheel cu130 เท่านั้น pip ธรรมดาอาจได้รุ่น CPU
  3. Python venv แยกทุกโปรเจกต์ — อย่าลงแพ็กเกจปนกับระบบ (เราเคยเจอ numpy คนละรุ่นชนกับแพ็กเกจระบบ ไล่แก้กันหลายชั่วโมง)
  4. GPU นี้คือ sm_121 — software บางตัวยัง JIT/compile ให้ไม่ได้ (เช่น torch.compile ยังใช้ไม่ได้ ให้ปิด) ถ้าเจอ “no kernel image available” คือเรื่องนี้
  5. pkill -f <ชื่อ> ระวัง match คำสั่งตัวเอง/session ssh ตัวเอง — ใช้ pattern แคบๆ และดู pgrep -af ก่อนฆ่าเสมอ (ทีมเราโดนมา 4 รอบในวันเดียว)

1.9 Checklist ก่อนไปบทถัดไป

  • [ ] uname -m = aarch64, nvidia-smi เห็น GB10
  • [ ] ssh จากเครื่องตัวเองด้วยชื่อ .local + key ติดแล้ว
  • [ ] ใช้ tmux เป็น: new / detach (Ctrl+b,d) / attach — และรู้ว่า exit ≠ detach
  • [ ] docker รัน --runtime=nvidia ผ่าน
  • [ ] (แนะนำ) Tailscale ติดแล้ว — ทดสอบ ssh ผ่านชื่อ ts.net จากมือถือ (ปิด WiFi ใช้ 4G) หนึ่งครั้ง
  • [ ] รู้ว่าดิสก์เหลือเท่าไหร่ (โมเดลจะกินที่เร็วมาก — เช็ค df -h / ก่อนดาวน์โหลดโมเดลทุกครั้ง)

→ บทที่ 2: ติดตั้ง AI Suite

1.10 เมื่อมีปัญหา (Troubleshooting)

อาการ: nvidia-smi ขึ้น Failed to initialize NVML: Driver/library version mismatch

ดูเหมือนเครื่องเสีย แต่จริงๆ ไม่ใช่ — สาเหตุ: มีการอัปเดต NVIDIA driver (จาก full-upgrade หรือ auto-update) แล้วยังไม่ได้รีบูต โมดูลเก่าใน kernel เลยไม่ตรงกับ library ตัวใหม่บนดิสก์
วิธีแก้: sudo reboot — จบ (เจอบ่อยกับเครื่องที่เปิดต่อเนื่องนานๆ เพราะระบบ auto-update ทำงานเงียบๆ)

อาการ: หลังอัปเดตใหญ่ ชื่อเครื่องเปลี่ยนเอง (เช่น gx10-xxxx กลายเป็น spark-xxxx)

สาเหตุ: อัปเดตใหญ่ของ DGX OS เปลี่ยน template ชื่อเครื่องอัตโนมัติ ทำให้ระบบที่อ้างชื่อเดิม (.local, config ต่างๆ) หาเครื่องไม่เจอ
วิธีแก้: ใช้ชื่อใหม่ (เช็คด้วยคำสั่ง hostname บนเครื่อง) แล้วไล่อัปเดตที่ที่อ้างชื่อเก่า
วิธีกันเกิดซ้ำ: ตรึงชื่อด้วย sudo hostnamectl set-hostname <ชื่อที่ต้องการ> — ชื่อที่ตั้งมือจะไม่ถูกเปลี่ยนทับอีก

อาการ: ssh หาเครื่องไม่เจอเลยทุกชื่อทุก IP แต่มือถือเห็น WiFi ชื่อ spark-xxxx โผล่มา

สาเหตุ (เจอกับตัวเรา): อัปเดตใหญ่ล้าง WiFi profile ทั้งหมด เครื่องเลยถอยเข้าโหมดแกะกล่อง — เปิด hotspot ตั้งค่าของตัวเองแทนการต่อเน็ต (มี service เฝ้าเปิด hotspot ซ้ำด้วย ปิดเฉยๆ ไม่อยู่)
วิธีแก้: ต่อจอ + คีย์บอร์ด + เมาส์ → เครื่องจะพาเข้าหน้าตั้งค่าเหมือนเปิดครั้งแรก ทำตามหน้าจอจนจบ (ต่อ WiFi ใหม่) → ดู IP WiFi (หัวข้อ 1.4) → ใช้งานต่อได้ตามปกติ
สำหรับผู้ดูแลระบบที่ถนัด terminal และอยากปิด hotspot ให้ขาดด้วยมือ:

sudo systemctl disable --now dgx-oobe-hotspot-watchdog.service dgx-oobe-hotspot.service
sudo nmcli connection delete OobeHotspot
sudo nmcli device wifi rescan && sleep 4
sudo nmcli device wifi connect "ชื่อWiFi" password "รหัสผ่าน"

เสร็จแล้วอย่าลืมสร้างโปรไฟล์ WiFi เริ่มต้น (ตามใบส่งมอบ) กลับคืนด้วย — ไม่งั้นกุญแจสำรองของหัวข้อ 1.4 จะหายถาวร

อาการ: .local ใช้ไม่ได้ / ping แล้วได้ IP แปลกๆ ที่เข้าไม่ถึง

ดูหัวข้อ “ทักษะเอาตัวรอด: ดู IP ของเครื่องให้เป็น” ใน 1.4 — ส่วนใหญ่คือเครื่องหลายเครือข่ายประกาศ IP ผิดวง ทางลัดคือ ssh ด้วย IP WiFi ตรงๆ


← สารบัญคู่มือ · บทที่ 2: ติดตั้งและใช้งาน AI Server →