مجھے وہ Samsung Galaxy Note 3 Android فون یاد ہے جو میری والدہ نے اپنے بلیک بیری کے کھونے کے بعد بچپن میں خریدا تھا۔ اس وقت، 16GB سٹوریج والے فونز کو جدید ٹیکنالوجی سمجھا جاتا تھا۔ ایک فون پر پانچ 720p ٹورینٹ فلموں کو اسٹور کرنے کے قابل ہونا ایمانداری سے غیر حقیقی تھا۔
اس وقت، زیادہ تر فلیگ شپ آلات 2GB اور 8GB کے درمیان RAM کے ساتھ آتے تھے اور GPUs اس کے قریب نہیں تھے جو ہم آج لے رہے ہیں۔ میری ماں کے گلیکسی نوٹ 3 میں Qualcomm Adreno 330 GPU تھا جس میں 32 انٹیگریٹڈ شیڈر کور 578 میگاہرٹز تک چل رہے تھے، جو اس وقت کے لیے بہترین تھا۔
آج، ہماری جیبوں میں موجود سیل فونز بہت زیادہ طاقتور، زیادہ موثر، اور واضح طور پر، وہ کام کرنے کے قابل ہیں جنہیں اس وقت لوگ سائنس فکشن سمجھتے تھے۔
لیکن ماں کی فون کال کے بارے میں کافی ہے۔ میں واقعی میں یہ کہنے کی کوشش کر رہا ہوں کہ AI سبسکرپشنز اور ٹوکنز پر ہر ماہ سیکڑوں ڈالر خرچ کرنے کے بجائے، ہم ان ناقابل یقین حد تک طاقتور آلات سے فائدہ اٹھا سکتے ہیں جو ہم پہلے ہی ہر روز اپنے ساتھ رکھتے ہیں۔
جدید سمارٹ فونز میں اب AI ایکسلریشن، متاثر کن تھرمل کارکردگی، اور ہلکے وزن والے لینگویج ماڈلز کو مقامی طور پر اور مکمل طور پر آف لائن چلانے کے لیے کافی کمپیوٹ پاور ہے۔ اس کا مطلب ہے رازداری میں اضافہ، آپ کی چیٹ کی سرگزشت پر مکمل کنٹرول، کم تاخیر، اور کلاؤڈ سروسز پر مکمل انحصار کیے بغیر AI استعمال کرنے کی صلاحیت۔
اس مضمون میں، ہم ایک React Native ایپلی کیشن بنائیں گے جو LLM کے ساتھ تعامل کرتا ہے جو براہ راست ڈیوائس پر چلتا ہے۔ نفاذ کے مراکز QVAC کے ارد گرد ہیں، خاص طور پر مقامی طور پر AI ماڈلز کو چلانے کے لیے ڈیزائن کردہ انفرنس ٹولز کا ایک مجموعہ۔
انڈیکس
شرائط
اس مضمون سے زیادہ سے زیادہ فائدہ اٹھانے کے لیے، آپ کو فرنٹ اینڈ ڈیولپمنٹ اور عام طور پر ردعمل کی بنیادی سمجھ ہونی چاہیے۔ آپ کو موبائل ڈویلپر بننے کی ضرورت نہیں ہے، لیکن React کو سمجھنے سے آپ کو بہت مدد ملے گی۔
QVAC کیا ہے؟
QVAC (QuantumVerse Automatic Computer) ایک مقامی-پہلا AI انفرنس پلیٹ فارم ہے جسے Tether نے تیار کیا ہے۔ یہ مصنوعی ذہانت کو سنٹرلائزڈ کلاؤڈ سسٹم سے دور لے جانے اور صارفین کے اپنے آلات پر کمپیوٹیشن کو واپس لانے کے لیے ڈیزائن کیا گیا ہے۔
زیادہ تر جدید AI ٹولز ریموٹ سرورز، API کیز، اور چند کمپنیوں کے زیر انتظام کلاؤڈ انفراسٹرکچر پر بہت زیادہ انحصار کرتے ہیں۔ اگرچہ یہ AI کو قابل رسائی بناتا ہے، یہ رازداری، سنسرشپ، وینڈر لاک ان، انٹرنیٹ پر انحصار، اور صارف کے ڈیٹا کی ملکیت کے بارے میں بھی بڑے خدشات کو جنم دیتا ہے۔ ہر پرامپٹ، گفتگو، یا اپ لوڈ کردہ فائل اکثر تھرڈ پارٹی سرورز سے گزرتی ہے جس پر آپ کا بہت کم کنٹرول ہوتا ہے۔
QVAC کو AI ماڈلز اور ایجنٹس کو سمارٹ فونز، لیپ ٹاپس اور ایمبیڈڈ سسٹم جیسے آلات پر براہ راست چلانے کی اجازت دے کر ان مسائل کو حل کرنے کے لیے ڈیزائن کیا گیا ہے، چاہے مکمل طور پر آف لائن ہو۔ ذاتی گفتگو اور حساس ڈیٹا کلاؤڈ پر بھیجنے کے بجائے، صارف اپنے ہارڈ ویئر پر مقامی طور پر ہر چیز کو سنبھال سکتے ہیں۔
یہ پلیٹ فارم پیئر ٹو پیئر (P2P) کمیونیکیشن کے ذریعے وکندریقرت کو بھی اپناتا ہے، مرکزی بنیادی ڈھانچے پر انحصار کو کم کرتا ہے اور ناکامی کے واحد نکات کو ختم کرتا ہے۔ یہ نقطہ نظر AI سسٹمز کو زیادہ نجی، لچکدار، خود مختار اور قابل رسائی بناتا ہے، خاص طور پر محدود انٹرنیٹ تک رسائی یا ڈیٹا پرائیویسی کے سخت تقاضوں والے ماحول میں۔
سادہ لفظوں میں، QVAC اس بات کو یقینی بنانے کے لیے موجود ہے کہ صارفین حقیقی معنوں میں AI کے مالک ہیں۔ اس کا مطلب ہے کہ یہ مقامی طور پر سب سے پہلے، بطور ڈیفالٹ نجی، اور مرکزی کنٹرول سے آزاد ہے۔
ترجیحات
عمل کو تیز کرنے کے لیے، ہم نے تمام انحصار کے ساتھ ایک React Native Starter پروجیکٹ تیار کیا ہے۔ لیکن چونکہ یہ ہمارا مرکزی موضوع ہے، اس لیے ہم اس مضمون میں QVAC کو انسٹال اور سیٹ اپ کریں گے۔ یہاں ذخیرہ کرنے کا ایک لنک ہے:
متبادل طور پر، آپ نیچے دی گئی کمانڈ کو چلا کر سٹارٹ اپ پروجیکٹ کو کلون کر سکتے ہیں:
git clone --branch ft-ui-implementation --single-branch https://github.com/DjibrilM/QVAC-offline-Chatbot-Article-Project-
HVAC کی تنصیب
SDK کو انسٹال کرنے کے لیے، درج ذیل کمانڈ کو چلائیں: npm i @qvac/sdk. آپ جو بھی پیکیج مینیجر چاہتے ہیں بلا جھجھک استعمال کریں۔ میں چیزوں کو آسان رکھوں گا۔ npm.
پھر درج ذیل ہم مرتبہ انحصار: package.json:
{
"dependencies": {
"@qvac/sdk": "^0.7.0",
+ "bare-rpc": "^1.0.0",
"expo": "~54.0.33",
"expo-status-bar": "~3.0.9",
"react": "19.1.0",
"react-native": "0.81.5",
+ "react-native-bare-kit": "^0.11.5"
},
"devDependencies": {
"@types/react": "~19.1.0",
"bare-pack": "^1.5.1",
"typescript": "~5.9.2"
}
}
درج ذیل اضافی انحصار انسٹال کریں:
npx expo install expo-file-system expo-build-properties expo-device
پھر ترتیب دیں۔ expo-build-properties اور شامل کریں @qvac/sdk/expo-plugin کو plugins آپ کا انتظام app.json:
{
"expo": {
"plugins": [
"expo-router",
"@qvac/sdk/expo-plugin",
[
"expo-splash-screen",
{
"backgroundColor": "#208AEF",
"android": {
"image": "./assets/images/splash-icon.png",
"imageWidth": 76
}
}
]
]
}
}
درج ذیل کمانڈ کو چلا کر مقامی ماڈیول بنائیں:
npx expo prebuild
میمو: QVAC اندرونی طور پر llama.cpp استعمال کرتا ہے۔ اصلاح کی ضروریات اور بنیادی ہارڈویئر انحصار کی وجہ سے، QVAC SDK ایمولیٹر پر نہیں چلتا ہے۔ آپ کو اس کی جانچ ایک حقیقی جسمانی ڈیوائس پر کرنی چاہیے جس میں ڈیولپر موڈ فعال ہو۔
ایپ کو حقیقی ڈیوائس پر چلانے کے لیے، چلائیں:
# For Android:
npx expo run:android --device
# For iOS:
npx expo run:ios --device
ماڈل مینجمنٹ
QVAC ماڈل مینجمنٹ سسٹم مکمل طور پر لوکل فرسٹ اور ڈی سینٹرلائزڈ ہے۔ یہ فائل ڈاؤن لوڈز سے لے کر لائف سائیکل آپٹیمائزیشن تک پورے لائف سائیکل کو ہینڈل کرتا ہے، اور کلین یوٹیلیٹی API کے پیچھے ہر چیز کا خلاصہ کرتا ہے۔
دوبارہ شروع کرنے کے قابل اور نقل شدہ ڈاؤن لوڈز (downloadAsset)
مقامی ڈسک پر عارضی ٹکڑوں کو لکھیں۔ اگر نیٹ ورک کی بندش ہوتی ہے تو، جزوی فائلیں محفوظ ہوجاتی ہیں اور اگلی کال پر خود بخود دوبارہ شروع ہوجاتی ہیں۔ مزید برآں، جب متعدد اجزاء ایک ہی اثاثہ کے لیے بیک وقت ڈاؤن لوڈز کو کال کرتے ہیں، تو QVAC ایک نیٹ ورک اسٹریم سے اسٹریمنگ کو ہینڈل کرتا ہے۔
میموری لائف سائیکل (loadModel اور unloadModel)
loadModel اثاثہ فائلوں کو براہ راست میموری میں نقشہ بنائیں، انہیں ہارڈویئر اہداف (جیسے ڈیوائس GPU) پر نقشہ بنائیں، اور پھر عارضی فائلوں کو بے نقاب کریں۔ modelId. کیونکہ مقامی اندازہ موبائل آلات پر زیادہ میموری ہے۔ unloadModel ڈسک پر ڈاؤن لوڈ کی گئی فائلوں کو محفوظ کرتے ہوئے فوری طور پر سسٹم ریم کو آزاد کر دیتا ہے۔
اپنی مرضی کے ماڈل
QVAC اوپن سورس AI ماحولیاتی نظام کے ساتھ اعلی مطابقت کو برقرار رکھتا ہے کیونکہ یہ llama.cpp کی بہترین شاخوں پر انحصار کرتا ہے۔ اگر آپ حسب ضرورت ماڈل لوڈ کرنے کا ارادہ رکھتے ہیں، تو یقینی بنائیں کہ یہ درج ذیل معیارات پر عمل پیرا ہے:
-
فارمیٹ: GGUF میں ہونا ضروری ہے (
.gguf) فارمیٹ۔ -
کوانٹائزیشن: جب موبائل اور کنارے کی تعیناتیوں کی بات ہو تو ہمیشہ ترجیح دیں۔
Q4_0،Q4_K_MیاQ8_0اسے اپنے موبائل ہارڈویئر RAM کی رکاوٹوں کے اندر محفوظ طریقے سے فٹ ہونے کے لیے ترتیب دیں۔
مکمل نفاذ
اب آئیے UI کنٹینر لے آؤٹ، صارف کے تعامل کی حالت، ماڈل لائف سائیکل سیٹنگز، اور ریئل ٹائم انفرنس پروسیسنگ کو ایک مربوط ڈھانچے میں یکجا کرتے ہوئے، بنیادی فائل کوڈبیس منطق کو مکمل نفاذ کے ساتھ تبدیل کریں۔
اپنی آئٹم فائل کو درج ذیل کوڈ سے تبدیل کریں:
import { ChatInput } from "@/components/chat-input";
import { ChatMessage, Message } from "@/components/chat-message";
import { ModelLoader } from "@/components/model-loader";
import { Button } from "@/components/ui/button";
import { Text } from "@/components/ui/text";
import {
completion,
deleteCache,
downloadAsset,
LLAMA_3_2_1B_INST_Q4_0,
loadModel,
type ModelProgressUpdate,
VERBOSITY,
} from "@qvac/sdk";
import { SymbolView } from "expo-symbols";
import { useEffect, useRef, useState } from "react";
import {
Clipboard,
KeyboardAvoidingView,
Platform,
SafeAreaView,
ScrollView,
View,
} from "react-native";
const makeId = () => Math.random().toString(36).substring(2, 9);
export default function Index() {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState("");
const [isGenerating, setIsGenerating] = useState(false);
// Model loading state
const [modelId, setModelId] = useState(null);
const [isModelLoaded, setIsModelLoaded] = useState(false);
const [isDownloading, setIsDownloading] = useState(false);
const [downloadProgress, setDownloadProgress] = useState(0);
const scrollViewRef = useRef(null);
const messagesRef = useRef([]);
useEffect(() => {
messagesRef.current = messages;
}, [messages]);
const startDownload = () => {
setIsDownloading(true);
setupModel();
};
// Automatically scroll to bottom when messages list updates
useEffect(() => {
if (scrollViewRef.current) {
setTimeout(() => {
scrollViewRef.current?.scrollToEnd({ animated: true });
}, 100);
}
}, [messages, isGenerating]);
const copyToClipboard = (text: string) => {
if (Platform.OS === "web") {
navigator.clipboard.writeText(text);
} else {
Clipboard.setString(text);
}
};
const setupModel = async () => {
try {
setIsDownloading(true);
setDownloadProgress(0);
// 1. Local download path execution
await downloadAsset({
assetSrc: LLAMA_3_2_1B_INST_Q4_0,
onProgress: (progress: ModelProgressUpdate) => {
setDownloadProgress(progress.percentage / 100);
},
});
setDownloadProgress(1);
// 2. Load model into runtime memory
const loadedModel = await loadModel({
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
modelType: "llm",
modelConfig: {
device: "gpu",
ctx_size: 2048,
verbosity: VERBOSITY.ERROR,
},
});
setModelId(loadedModel);
setIsModelLoaded(true);
setIsDownloading(false);
} catch (e: any) {
console.error("Error setting up model:", e);
setIsDownloading(false);
}
};
async function handleSend() {
// Guard against sending before the model is ready or while generating.
if (!modelId || isGenerating) return;
const trimmed = input.trim();
if (!trimmed) return;
setInput("");
setIsGenerating(true);
// Append user message and a placeholder assistant message for streaming.
const userMsg: Message = {
id: makeId(),
role: "user",
content: trimmed,
};
const assistantId = makeId();
const assistantMsg: Message = {
id: assistantId,
role: "assistant",
content: "",
};
setMessages((prev) => [...prev, userMsg, assistantMsg]);
try {
// Build chat history for the completion request.
const history = [...messagesRef.current, userMsg].map((m) => ({
role: m.role,
content: m.content,
}));
// Run a streaming completion and update the last assistant bubble.
const result = completion({
modelId,
history,
stream: true,
});
let acc = "";
for await (const token of result.tokenStream) {
acc += token;
// Update only the last assistant message content
setMessages((prev) =>
prev.map((m) =>
m.id === assistantId ? { ...m, content: acc } : m
)
);
}
// Optional: Log completion performance stats
try {
const stats = await result.stats;
console.log("📊 Completion stats:", stats);
} catch {}
} catch (e: any) {
// Show any error in the assistant bubble.
setMessages((prev) =>
prev.map((m) =>
m.id === assistantId
? { ...m, content: `❌ Error: ${e?.message ?? String(e)}` }
: m
)
);
} finally {
setIsGenerating(false);
}
}
if (!isModelLoaded) {
return (
);
}
return (
Local Llama 3.2
Offline Engine
{messages.filter(m => m.content !== "" || m.role === "assistant").map((msg) => (
copyToClipboard(msg.content)}
/>
))}
);
}
کوڈ بیس تجزیہ
آئیے اس پر گہری نظر ڈالتے ہیں کہ یہ مربوط جزو کس طرح مقامی ماڈل کے ورک فلو اور ریئل ٹائم UI اسٹریمنگ کا انتظام کرتا ہے۔
1. ماڈل اسٹیٹ ٹریکنگ اور غیر مطابقت پذیر ہم آہنگی۔
صارف کا سامنا کرنے والے انٹرفیس کی حالت اور جزو کی جڑ میں بنیادی QVAC رن ٹائم ہینڈل دونوں کو ٹریک کرتا ہے۔
const [messages, setMessages] = useState([]);
const [modelId, setModelId] = useState(null);
const [isModelLoaded, setIsModelLoaded] = useState(false);
const [isDownloading, setIsDownloading] = useState(false);
const [downloadProgress, setDownloadProgress] = useState(0);
ری ایکٹ کے اسٹیٹ سیٹرز غیر مطابقت پذیر ہیں، اس لیے سٹریمنگ لوپس غلطی سے موجودہ چیٹ لاگ کی باسی نمائندگی کو پکڑ سکتے ہیں۔
اس سے بچنے کے لیے، قابل تبدیلی messagesRef یہ فعال سیشن کی حیثیت کے لئے حقیقی وقت کے واحد ذریعہ کے طور پر کام کرتا ہے۔
const messagesRef = useRef([]);
useEffect(() => {
messagesRef.current = messages;
}, [messages]);
2. ڈاؤن لوڈ اور میموری انسٹیٹیشن کو ایڈجسٹ کریں۔
جب صارف ڈاؤن لوڈ بٹن ایکشن ٹرگر دباتا ہے تو ایپلیکیشن چلتی ہے۔ setupModel(). یہ خصوصیت واضح طور پر کاموں کو مقامی اسٹوریج کیشنگ اور فعال ہارڈویئر مختص درجات میں تقسیم کرتی ہے۔
await downloadAsset({
assetSrc: LLAMA_3_2_1B_INST_Q4_0,
onProgress: (progress: ModelProgressUpdate) => {
setDownloadProgress(progress.percentage / 100);
},
});
-
اسٹوریج کی مطابقت پذیری:
downloadAssetمخصوص معیاری ماڈل کے دستخط کو موبائل ڈیوائس ڈسک فائل میں درآمد کرنے کے لیے پہنچ جاتا ہے۔ -
ہارڈ ویئر بائنڈنگ: اگر یہ ڈسک پر محفوظ ہے۔
loadModelانجن کے رن ٹائم کو جگانے کے لیے دوڑتا ہے۔
const loadedModel = await loadModel({
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
modelType: "llm",
modelConfig: {
device: "gpu",
ctx_size: 2048,
verbosity: VERBOSITY.ERROR,
},
});
گزرنا device: "gpu" یہ QVAC کو سمارٹ فون کے گرافکس پروسیسنگ ہارڈویئر فن تعمیر میں ہارڈ ویئر کے تیز دانے چلانے کی ہدایت کرتا ہے، جس سے تیز رفتار کارکردگی کے میٹرکس کو یقینی بنایا جاتا ہے بجائے اس کے کہ ایک سست سی پی یو لوپ میں عملدرآمد کو لاک کیا جائے۔
3. پائپ لائن ادخال اور اسٹریمنگ تخلیق لوپ
ایک بار جب صارف کی تصدیق اس بات کی تصدیق کرتی ہے کہ پرامپٹ تیار ہے: handleSend() ٹوکن آؤٹ پٹ سیگمنٹ کیپچر کرنے کے لیے صارف کا بلبلہ ترتیب دیں اور ایک خالی ثانوی پلیس ہولڈر کارڈ بنائیں۔
درخواست کے نقشے حوالہ جات کا براہ راست ترجمہ کرتے ہیں۔ messagesRef.current پروسیسنگ سے پہلے ساختی تاریخ کے نحو کے ساتھ:
const result = completion({
modelId,
history,
stream: true,
});
کے ساتھ stream: true فعال ہونے پر، QVAC ایپلیکیشن تھریڈز کو لمبے سٹرنگ سیکوینس کے مکمل ہونے کے انتظار میں تاخیر نہیں کرے گا۔ اس کے بجائے، یہ ایک غیر مطابقت پذیر ریپیٹ ایبل اسٹریم بناتا ہے جو فوری طور پر نئی اپ ڈیٹس کو آگے بڑھاتا ہے۔
let acc = "";
for await (const token of result.tokenStream) {
acc += token;
setMessages((prev) =>
prev.map((m) =>
m.id === assistantId ? { ...m, content: acc } : m
)
);
}
لوپ ٹوکن ٹیکسٹ متغیر کو جمع کرنے والے میں ٹریک کرتا ہے (acc) پلیس ہولڈر شناخت کنندہ (assistantId)۔ یہ صارف کے فزیکل ڈیوائس ہارڈ ویئر پر مکمل طور پر آف لائن چلتے ہوئے تیز رفتار ٹائپنگ اینیمیشن کا تجربہ بناتا ہے۔
نتیجہ
مقامی-پہلی AI ایپلی کیشنز کی تعمیر اب صرف اعلیٰ درجے کے ڈیسک ٹاپس یا خصوصی لیبز تک محدود نہیں ہے۔ جیسا کہ ہم نے دیکھا ہے، جو اسمارٹ فونز ہم ہر روز اپنی جیبوں میں رکھتے ہیں ان میں کافی کمپیوٹیشنل پاور اور ہارڈ ویئر ایکسلریٹر ہوتے ہیں جو اعلیٰ کارکردگی والے لینگویج ماڈلز کو مکمل طور پر آف لائن چلا سکتے ہیں۔
ہم نے React Native اور QVAC SDK کا فائدہ اٹھا کر روایتی کلاؤڈ پر منحصر فن تعمیر کو کامیابی کے ساتھ نظرانداز کیا۔ یہ پیچیدہ سرور انفراسٹرکچر، API کلیدی نظم و نسق، اور بار بار چلنے والی ٹوکن سبسکرپشن فیس کی ضرورت کو ختم کرتے ہوئے براہ راست آپ کے آلے پر ہائپر پرسنل، کم لیٹنسی اسٹریمنگ چیٹ کا تجربہ فراہم کرتا ہے۔
چونکہ اوپن سورس ماڈل سائز میں سکڑتے رہتے ہیں اور فعالیت میں اضافہ ہوتا ہے، کنارے کا اندازہ ان ڈویلپرز کے لیے ایک ضروری فن تعمیر بن جائے گا جو رازداری، آف لائن لچک اور لاگت کی تاثیر کو ترجیح دیتے ہیں۔ کمپیوٹنگ پاور واپس آ گئی ہے جہاں سے اس کا تعلق ہے: صارفین کے ہاتھ میں۔
وسائل اور اضافی وسائل
مقامی تخمینہ کے بارے میں مزید جاننے کے لیے، سورس کوڈ کا معائنہ کریں، یا موبائل ایپلیکیشنز کی جدید کنفیگریشن دریافت کریں، درج ذیل وسائل کو دیکھیں:
-
QVAC ایکسپو انٹیگریشن ٹیوٹوریل – ایکسپو کے اندر QVAC کو ترتیب دینے اور مقامی ماحولیاتی نظام کو رد کرنے کے لیے باضابطہ مرحلہ وار دستاویزات۔
-
پروجیکٹ GitHub ذخیرہ – مکمل سورس کوڈ تک رسائی حاصل کریں، بشمول UI لے آؤٹ کے اجزاء، سٹارٹ اپ تھیم، اور اس گائیڈ میں استعمال کی گئی مکمل کنفیگریشن فائلز۔
-
Llama.cpp آفیشل ریپوزٹری – بنیادی انفرنس انجن کے بارے میں مزید جانیں جو QVAC کے ہارڈویئر تیز رفتار مقامی عمل کو سپورٹ کرتا ہے۔
-
گلے ملنے والا چہرہ GGUF ماڈل – ہزاروں اوپن سورس کوانٹائزیشن ماڈلز دریافت کریں جنہیں آپ اپنی مقامی ایپلیکیشن میں ڈاؤن لوڈ اور تجربہ کر سکتے ہیں۔