อยากใช้ AI ให้เต็มที่ แต่ก็ยังแอบกังวลเรื่องข้อมูลส่วนตัว

ลองทำ Privacy Filter ให้ AI ด้วยเครื่องเก่าที่บ้าน

ผมใช้ AI ในชีวิตประจำวันมากขึ้นเรื่อยๆ ทั้ง Claude ทั้ง Gemini ช่วยเขียนโค้ด คิดงาน แก้ปัญหา
แต่มีบางวันที่อยากถามเรื่องที่อ่อนไหวหน่อย เช่น ให้ดูฟอร์มที่มีเลข SSN (เลขประกันสังคมของสหรัฐฯ) ให้ดีบัก config ที่มี password
ให้ช่วยอ่าน email ที่มีข้อมูลสำคัญ หรือให้ตรวจสอบเรื่องบัญชีธนาคาร

“แล้วผมก็หยุดคิดว่า ข้อมูลพวกนี้ถูกส่งขึ้น server ของบริษัทอื่นทั้งหมดนะ”

จริงๆ ก็เชื่อใจ Google กับ Anthropic อยู่แล้วนะ ฮ่าๆ แต่ก็แอบไม่สบายใจ
เลยคิดว่าลองทำ project สนุกๆ ดูดีกว่า


จุดเริ่มต้น: อยากรันทุกอย่างในเครื่องตัวเอง

แผนแรกคือรัน AI ทั้งหมดใน local (ในเครื่องตัวเอง ไม่ผ่านอินเทอร์เน็ต) ไม่ต้องส่งข้อมูลออกเลย ตอนนั้น Gemma 4 เพิ่งออก
ก็ลองเลย ใช้ผ่าน Open WebUI (หน้าเว็บสำหรับคุยกับ AI ที่รันในเครื่อง) ด้วย

เริ่มจาก e4b ก่อน เพราะน่าจะเป็น model ที่เล็กที่สุดที่เข้าใจ image ได้ด้วย
แต่ผลคือ… ช้ามากครับ โมเดลมันใหญ่เกิน VRAM (หน่วยความจำของ GPU) 4GB ของผม เลย spill ลง CPU
(เมื่อ VRAM ไม่พอ โมเดลจะดึง RAM ปกติมาใช้แทน ซึ่งช้ากว่ากันมาก)
response ทีนึงนาน 38 วินาที ใช้ผ่าน Open WebUI ยิ่งช้าลงอีก

เครื่องผม: คอมเก่าที่บ้าน ใส่ GPU (ชิปประมวลผลกราฟิก) NVIDIA GTX 1050 Ti VRAM แค่ 4GB รัน Ubuntu Server เปิดตลอด 24 ชั่วโมง

ทางเลือกอื่นที่คิดถึง:

ตัวเลือกปัญหา
รันทุกอย่าง localต้องการ VRAM เยอะ โมเดลดีๆ ต้องการ 16GB+
ใช้ cloud AI ตรงๆข้อมูลส่วนตัวออกจากเครื่องไปอยู่บน server ของบริษัทอื่นทั้งดุ้น
เช่า cloud GPU server (เช่าเครื่องพลังสูงออนไลน์)$150-300/เดือน แถมข้อมูลก็ยังออกนอกบ้านอยู่ดี

ไอเดีย: Screen ก่อนส่ง

คิดขึ้นมาเองว่า ถ้าลบข้อมูลส่วนตัวออกก่อนที่มันจะออกจากบ้าน cloud AI ก็จะเห็นแค่ข้อความสะอาดๆ

เอาไอเดียนี้ไปคุยกับ Claude ดูว่าเป็นไปได้ไหม แล้วไปค้นดูว่ามีคนทำแบบนี้กันบ้างไหม ปรากฎว่ามี concept นี้อยู่จริงๆ
เลยลองทำดู

แผนคือสร้าง proxy server (ตัวกลางที่รับส่งข้อมูลแทนเรา) ที่นั่งอยู่กลางระหว่างเราและ cloud AI:

อุปกรณ์เรา (โทรศัพท์ / แล็ปท็อป)
PII Proxy (FastAPI, port 8000)
รันบนเครื่องเก่าที่บ้าน
  1. ตรวจสอบ API key (รหัสสำหรับพิสูจน์ตัวตนว่าใครเป็นคนส่งข้อมูล)
  2. สแกนข้อความด้วย AI ในเครื่อง
  3. แทนที่ PII ด้วย [SSN] [PASSWORD]
  4. ส่งข้อความสะอาดไป cloud
  5. ส่งคำตอบกลับมา
Groq API / Gemini API (free tier)

จุดสำคัญ: cloud model ไม่เคยเห็นข้อมูลจริงๆ มันเห็นแค่ [SSN], [CREDIT_CARD], [PASSWORD] แทน


เลือก Local Model สำหรับ Screen

ทดสอบกับ Claude ว่าโมเดลไหนน่าจะ fit กับเครื่องที่มี ดูหลายตัว สุดท้ายได้ผลนี้:

ลองไปหลายตัวเรียงกัน:

โมเดลขนาดผล
Gemma 4 27B~16GBใช้ไม่ได้เลย VRAM ไม่พอ
Gemma 4 e4b9.6GBSpill ลง CPU ช้ามาก ~38 วินาที/ตอบ
Gemma 4 e2b7.2GBเร็วขึ้นหน่อย แต่ยังช้า และไม่รองรับ image
qwen2.5vl:3b3.2GBเร็ว แต่ benchmark (ผลทดสอบความแม่นยำ) PII screening ไม่ดีเท่า
phi4-mini2.5GBเร็ว แต่ benchmark PII screening ไม่ดีเท่า
gemma3:4b3.3GBFit VRAM พอดี เร็ว รองรับ image ✓

ที่เลือก gemma3:4b ไม่ใช่แค่เพราะขนาดหรือความเร็ว โมเดลนี้รองรับ image ด้วย
ซึ่ง e2b ทำไม่ได้ เผื่อในอนาคตถ้าส่ง screenshot ไปให้ AI
โมเดลนี้จะสแกน sensitive data ในภาพได้ก่อนส่งออก

บทเรียน: โมเดลเล็กที่ fit ใน VRAM เร็วกว่าโมเดลใหญ่ที่ spill ลง CPU มากกว่า 10 เท่า


สิ่งที่ Proxy ตรวจจับ

ใช้วิธี hybrid คือผสม regex (การค้นหาข้อความด้วย pattern เช่น “ตัวเลข 9 หลักที่มีขีด”) กับ LLM (โมเดล AI ที่เข้าใจความหมายของภาษา) เข้าด้วยกัน แทนที่จะใช้อย่างใดอย่างหนึ่ง

Regex (เร็ว แม่นยำ 100% สำหรับ format คงที่)

  • SSN: XXX-XX-XXXX, XXX XX XXXX, ssn#XXXXXXXXX[SSN]
  • บัตรเครดิต 16 หลัก (Visa, MC, Discover) → [CREDIT_CARD]
  • บัตรเครดิต 15 หลัก (Amex) → [CREDIT_CARD]
  • Routing number (รหัสธนาคาร) / Account number (หมายเลขบัญชี) → [ROUTING], [ACCOUNT]

LLM — gemma3:4b (เฉพาะสิ่งที่ไม่มี format คงที่)

  • Password และ passphrase → [PASSWORD]
  • รันเฉพาะเมื่อเจอคีย์เวิร์ด “password”, “passwd”, “secret”, “pin” เท่านั้น
  • ข้อความทั่วไปที่ไม่มีคีย์เวิร์ดพวกนี้ ข้าม LLM ไปเลย เร็วขึ้นมาก

ทำไมถึงต้อง Hybrid?

เวอร์ชันแรกผมใช้ gemma3:4b สแกนทุกอย่าง ปัญหาที่เจอ:

  • โมเดลแทนที่คำว่า “ssn” แทนที่จะแทนที่ตัวเลข 482-91-7823
  • ผลลัพธ์ไม่สม่ำเสมอ ขึ้นอยู่กับว่าเขียนประโยคยังไง

SSN มี format ตายตัว regex จัดการได้ดีกว่า เร็วกว่า แม่นกว่า
แต่ password ไม่มี format ตายตัว LLM เข้าใจ context ได้ดีกว่า


Caching: แก้ปัญหาที่ไม่ได้คาดไว้

พอใช้กับ Open WebUI ก็เจอปัญหาที่ไม่ได้คาดไว้ UI นี้ส่ง conversation history (ประวัติการสนทนาทั้งหมดตั้งแต่ต้น) ทุกครั้งที่ส่งข้อความใหม่

คุยไป 10 รอบ รอบที่ 10 proxy ต้องสแกน 10 ข้อความ ทั้งที่ 9 ข้อความแรกสแกนไปแล้ว ช้าโดยไม่จำเป็น

วิธีแก้คือ cache (เก็บผลที่คำนวณไว้แล้วไว้ใช้ซ้ำ) ด้วย SHA-256 hash (รหัสเฉพาะที่สร้างจากเนื้อหาข้อความ ถ้าข้อความเหมือนกันทุกตัวอักษร hash จะเหมือนกันเป๊ะ) ถ้าเจอข้อความที่เคยสแกนแล้ว คืนผลทันทีโดยไม่ต้องถาม AI อีกรอบ

_cache: dict[str, str] = {}

def _hash(value: str) -> str:
    return hashlib.sha256(value.encode()).hexdigest()

async def screen_text(text: str) -> str:
    key = _hash(text)
    if key in _cache:
        return _cache[key]  # ไม่ต้องถาม LLM
    # ... เรียก gemma3:4b ...
    _cache[key] = result
    return result

API Design: Compatible กับ OpenAI

Proxy ทำงานในรูปแบบเดียวกับ OpenAI API (มาตรฐานการเชื่อมต่อที่แอปและ UI ส่วนใหญ่รองรับ) เลย ไม่ต้องแก้โค้ด client แค่เปลี่ยน URL

POST http://YOUR_SERVER_IP:8000/v1/chat/completions
Authorization: Bearer <your-key>

{
  "model": "screened/groq/llama-3.3-70b-versatile",
  "messages": [{"role": "user", "content": "my ssn is 482-91-7823"}]
}

Convention ของชื่อ model:

  • groq/llama-3.3-70b-versatile → ส่งตรงไป Groq ไม่สแกน
  • screened/groq/llama-3.3-70b-versatile → สแกนก่อน แล้วส่ง Groq
  • screened/gemini-2.0-flash → สแกนก่อน แล้วส่ง Gemini

ทุก response มี metadata บอกว่าผ่าน screening หรือเปล่า:

"x_pii_proxy": {
  "screened": true,
  "screen_time_s": 1.23,
  "screener_model": "gemma3:4b"
}

ผลการทดสอบ

InputOutputผล
my ssn is 482-91-7823my ssn is [SSN]
social security 482 91 7823social security [SSN]
ssn#482917823ssn#[SSN]
my visa is 4111 1111 1111 1111my visa is [CREDIT_CARD]
my password is Hunter2@securemy password is [PASSWORD]
passwd: abc123passwd: [PASSWORD]
order #482917823 please shipไม่เปลี่ยน✓ ไม่ false positive (ไม่แทนที่ผิดพลาด)
I scored 4111 pointsไม่เปลี่ยน✓ ไม่ false positive
what is an SSN?ไม่เปลี่ยน✓ ถามเฉยๆ ไม่มีเลข

ค่าใช้จ่าย

รายการค่าใช้จ่าย
คอมเก่าที่บ้าน + GTX 1050 Tiมีอยู่แล้ว
Groq free tier (แพ็กเกจฟรี 14,400 req/วัน)$0
Gemini free tier (แพ็กเกจฟรี 1,500 req/วัน)$0
ค่าไฟ~$5-10/เดือน
รวม~$5-10/เดือน

เทียบกับเช่า cloud GPU server: $150-300/เดือน


สิ่งที่ได้เรียนรู้

  1. Hybrid regex+LLM ดีกว่า LLM อย่างเดียว ใช้ regex สำหรับ format คงที่ ใช้ LLM เฉพาะส่วนที่ต้องเข้าใจ context
  2. VRAM คือข้อจำกัดจริงๆ โมเดลที่ fit ใน VRAM เร็วกว่าที่ spill ลง CPU มากกว่า 10 เท่า
  3. OpenAI-compatible API ตัดสินใจถูก client ทุกตัว ทุก UI ใช้ได้เลยโดยไม่ต้องแก้โค้ด
  4. Cache conversation history จำเป็นมาก สำหรับ chat UI ที่ส่ง history ทั้งหมดทุกครั้ง
  5. Free tier ของ cloud พอสำหรับใช้ส่วนตัว Groq 14,400 req/วันเกินพอแล้ว

สรุป

โปรเจกต์นี้ทำสนุกๆ มากกว่าจะเป็น production-ready solution จริงๆ
และถ้าพูดตรงๆ ผมก็เชื่อใจ Anthropic กับ Google อยู่แล้วในระดับนึงนะ ฮ่าๆ
แต่ก็ได้เรียนรู้อะไรเยอะจากการทำ

ถ้าอยากใช้จริงจัง วิธีที่ดีที่สุดน่าจะเป็น build เครื่องมาสำหรับรัน local model โดยตรงเลย
แต่ถ้ายังไม่อยากลงทุน มีเครื่องเก่าอยู่บ้าน GPU ไม่แรงมากก็ลองทำ proxy แบบนี้ได้เลย
ต้นทุนแทบไม่มี แต่ได้เรียนรู้เยอะ

Tech stack สรุป: FastAPI + Ollama (gemma3:4b) + Groq/Gemini free tier + Open WebUI + systemd


Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *