اونیکس ai.onnx
خواندن و اجرای مدلهای ONNX بی وابستگی بیرونی.
واردسازی هوش مصنوعی.اونیکس
نام آرگومانها شناسهی خود کد است و معادل فارسی ندارد؛ گونهها، کلیدواژهها و نام بستهها با معادل فارسی نوشته میشوند.
ONNX قالب رایج تبادل مدلهای آموزشدیدهی یادگیری ماشین است. مدل را در PyTorch، TensorFlow یا scikit-learn آموزش دهید، یک بار به .onnx صادر کنید و این بسته آن را درون برنامهی سلام اجرا میکند، بی پایتون و بی کتابخانهی ONNX Runtime. بارگذاری اونیکس پرونده را میخواند، اجرا خروجیها را از تانسورهای ورودی شما حساب میکند و نتیجهها مقدارهای معمولی tensor هستند.
این بسته برای استنتاج است: امتیازدهی، دستهبندی و ساختن بردار جاسازی. برای آموزش یا تنظیم دقیق شبکه در خود سلام، آن را با nn و optim بسازید. برای مدلهای زبانی بزرگ در قالب GGUF به gguf و llm سر بزنید.
مفهومهای اصلی
مدلهمان گراف پرونده است: گرهها درnodesبه ترتیب اجرا، وزنها درinitsو نام ورودیها و خروجیهای گراف.نام ورودیهاورودیهایی را که شما میدهید به ترتیب فهرست میکند؛اجرابرای هر کدام یک تانسور میگیرد و برای هر خروجی گراف یک تانسور برمیگرداند.- هیچ چیز برنامه را متوقف نمیکند. هر شکستی آرگومان
okرا نادرست میکند و دلیلش را درerrorمدل میگذارد.
محدودیتهایی که پیش از صادر کردن باید بدانید
- همهی تانسورها در درون
اعشار۳۲هستند. وزنهای صحیح و دودقتی هنگام خواندن پرونده تبدیل میشوند، پسint64بزرگتر از ۱۶۷۷۷۲۱۶ دقتش را از دست میدهد. - حدود ۶۵ عملگر پیاده شده است، به اندازهی لایههای پیشخور، کانولوشنی و نرمالسازی (فهرست پایینتر آمده). هر چیز دیگری، مثل
LSTM،Resizeیا عملگرهای کوانتیده، باunsupported op: NAMEشکست میخورد. Convگروه ندارد (پس کانولوشن عمقی هم نه)، اتساع ندارد و فقط حاشیهی متقارن را میپذیرد.MaxPoolوAveragePoolحاشیه ندارند.- وزنها باید درون خود پروندهی
.onnxباشند. مدلهایی که با دادهی بیرونی صادر شدهاند (پروندهی جدای.dataکه بالای ۲ گیگابایت به کار میرود) بار نمیشوند. - شکل ورودیها با پرونده سنجیده نمیشود و نسخهی opset نادیده گرفته میشود. شکل نادرست به صورت خطای نخستین عملگری که نتواند با آن کار کند ظاهر میشود.
بررسی هر گام
هم تجزیه اونیکس (یا بارگذاری اونیکس) و هم اجرا موفقیت را با آرگومان آخرشان گزارش میدهند، یک منطقی که مقدارش را میگذارند، و دلیل را در فیلد error مدل مینویسند. پس از هر فراخوانی آن را بسنجید: فایلی که ONNX نیست، گرافی با عملگری که این بسته پیاده نکرده، یا شمار نادرست ورودیها، همه به همین شکل برمیگردند و برنامه را متوقف نمیکنند. مدل این مثال با encoding.protobuf در حافظه ساخته میشود، فقط یک Relu، پس برنامه بی هیچ فایلی اجرا میشود.
واردسازی هوش مصنوعی.اونیکس
واردسازی هوش مصنوعی.تانسور
واردسازی فشرده سازی
واردسازی کدگذاری.پروتوباف
تابع متن(ب &: فشرده سازی.بافر بایت، شماره: صحیح، مقدار: رشته):
پروتوباف.نوشتن برچسب(ب، شماره، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن رشته طولدار(ب، مقدار)
پایان
تابع زیرپیام(ب &: فشرده سازی.بافر بایت، شماره: صحیح، پیام: فشرده سازی.بافر بایت):
پروتوباف.نوشتن برچسب(ب، شماره، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن بایتهای طولدار(ب، پیام.داده، فشرده سازی.طول بافر(پیام))
پایان
تابع مدل یکسوساز(): فشرده سازی.بافر بایت:
ناپایا گره := فشرده سازی.بافر بایت جدید()
متن(گره، ۱، "x")
متن(گره، ۲، "y")
متن(گره، ۴، "Relu")
ناپایا خوراک ایکس := فشرده سازی.بافر بایت جدید()
متن(خوراک ایکس، ۱، "x")
ناپایا خروجی ایگرگ := فشرده سازی.بافر بایت جدید()
متن(خروجی ایگرگ، ۱، "y")
ناپایا گراف := فشرده سازی.بافر بایت جدید()
زیرپیام(گراف، ۱، گره)
زیرپیام(گراف، ۱۱، خوراک ایکس)
زیرپیام(گراف، ۱۲، خروجی ایگرگ)
ناپایا م := فشرده سازی.بافر بایت جدید()
پروتوباف.نوشتن برچسب(م، ۱، پروتوباف.نوع سیم متغیر)
پروتوباف.نوشتن عدد متغیر(م، ۸ برگردان طبیعی۶۴)
زیرپیام(م، ۷، گراف)
برگشت م
پایان
تابع ریشه:
ناپایا موفق := نادرست
آشغال := "this is not a model"
_ := اونیکس.تجزیه اونیکس(آشغال برگردان تهی*، آشغال.طول()، موفق)
سرچاپ "متن بیربط خوانده شد:"، موفق
ناپایا بایت ها := مدل یکسوساز()
ناپایا مدل := اونیکس.تجزیه اونیکس(بایت ها.داده، فشرده سازی.طول بافر(بایت ها)، موفق)
سرچاپ "مدل خوانده شد:"، موفق، "ورودیها:"، مدل.نام ورودیها().طول()
ناپایا هیچ := وکتور {} برگردان وکتور<تانسور.تانسور>
_ := اونیکس.اجرا(مدل، هیچ، موفق)
سرچاپ "اجرا بدون ورودی:"، موفق، "|"، مدل.خطا
ناپایا خوراک ها := وکتور {} برگردان وکتور<تانسور.تانسور>
خوراک ها.بیفزا(تانسور.بازه گام(۴) - تانسور.پرشده(تانسور.شکل یک(۴)، ۲.۰))
نتیجه ها := اونیکس.اجرا(مدل، خوراک ها، موفق)
سرچاپ "اجرا با x:"، موفق، تانسور.به رشته(نتیجه ها.بگیر(۰))
مدل.آزادسازی()
فشرده سازی.آزادسازی بافر(بایت ها)
پایاننام ورودیها ورودیهایی را که باید بدهید به ترتیب فهرست میکند. ورودیهایی از گراف را که در واقع وزنهای ذخیره شده در فایلاند کنار میگذارد؛ صادرکنندههای قدیمیتر آنها را هم جزو ورودیها میآورند.
نگاهی به درون فایل مدل
پیش از آن که مدلی را به برنامه وصل کنید، ببینید چه انتظاری دارد. این ابزار ورودیها و خروجیها، شمار گرههای هر عملگر در گراف و تعداد عددهای وزنها را چاپ میکند. آن را روی هر فایل .onnx اجرا کنید:
salam build onnx-guide-inspect.salam
./onnx-guide-inspect model.onnx
واردسازی هوش مصنوعی.اونیکس
واردسازی سیستم عامل
تابع ریشه:
آرگ ها := سیستم عامل.آرگومان ها()
اگر آرگ ها.طول() < ۲:
سرچاپ "روش کاربرد: onnx-guide-inspect model.onnx"
برگشت ۱
پایان
ناپایا موفق := نادرست
ناپایا مدل := اونیکس.بارگذاری اونیکس(آرگ ها.بگیر(۱)، موفق)
اگر وارونه موفق:
سرچاپ "مدل خوانده نشد:"، مدل.خطا
برگشت ۱
پایان
سرچاپ "نسخهی IR"، مدل.نسخه آی آر
سرچاپ "ورودیها"، مدل.نام ورودیها()، "خروجیها"، مدل.خروجیها
ناپایا شمار := نگاشت {} برگردان نگاشت<رشته، صحیح>
ناپایا ترتیب := وکتور {} برگردان وکتور<رشته>
هر گره در مدل.گرهها:
اگر شمار.دارد(گره.عملگر):
شمار.درج(گره.عملگر، شمار.بگیر(گره.عملگر) + ۱)
وگرنه:
شمار.درج(گره.عملگر، ۱)
ترتیب.بیفزا(گره.عملگر)
پایان
پایان
هر نام در ترتیب:
سرچاپ " " + نام، شمار.بگیر(نام)
پایان
ناپایا وزن ها := ۰
هر ت در مدل.وزنهای ثابت:
وزن ها += ت.شمار درایهها()
پایان
سرچاپ مدل.وزنهای ثابت.طول()، "تانسور وزن،"، وزن ها، "عدد"
مدل.آزادسازی()
پایانروی مدل کوچکی که مثال مرجع پایین همین صفحه مینویسد، این را چاپ میکند:
نسخهی IR 8
ورودیها ["x"] خروجیها ["y"]
Mul 1
LeakyRelu 1
1 تانسور وزن، 3 عدد
پیش از آن که چیزی روی یک مدل بسازید، شمار عملگرهایش را با فهرست پشتیبانیشده مقایسه کنید:
| دسته | عملگرها |
|---|---|
| جبر خطی | MatMul، Gemm، Conv |
| ریاضی عنصر به عنصر | Add، Sub، Mul، Div، Pow، Sqrt، Exp، Log، Abs، Neg، Reciprocal، Floor، Ceil، Round، Sign، Erf، Min، Max، Sum، Mean، Clip |
| تابعهای فعالسازی | Relu، LeakyRelu، PRelu، Elu، Selu، Gelu، Sigmoid، HardSigmoid، Tanh، Softplus، Softmax، LogSoftmax |
| نرمالسازی و ادغام | BatchNormalization، InstanceNormalization، LayerNormalization، MaxPool، AveragePool، GlobalAveragePool، Dropout (در استنتاج کاری نمیکند) |
| کاهش و منطق | ReduceSum، ReduceMean، ReduceMax، ReduceMin، Equal، Greater، Less، Where |
| شکل | Reshape، Flatten، Transpose، Concat، Split، Slice، Gather، Squeeze، Unsqueeze، Expand، Shape، Cast، Constant، Identity |
اجرای یک دستهبند آموزش دیده
مدل را هر جا راحتتر است آموزش دهید، یک بار صادرش کنید و در زمان اجرا بی هیچ پایتونی از سلام اجرایش کنید. با PyTorch، دستهبند گلهای زنبق با چهار ورودی و سه خروجی اینطور صادر میشود:
torch.onnx.export(model, torch.zeros(1, 4), "iris.onnx",
input_names=["x"], output_names=["logits"],
dynamic_axes={"x": {0: "batch"}})
برنامه دو گل را یکجا به شکل تانسوری 2x4 میدهد، لوجیتها را با بیشینه نرم از بستهی تانسور به احتمال تبدیل میکند و محتملترین دستهی هر سطر را برمیدارد.
واردسازی هوش مصنوعی.اونیکس
واردسازی هوش مصنوعی.تانسور
تابع ریشه:
ناپایا موفق := نادرست
ناپایا مدل := اونیکس.بارگذاری اونیکس("iris.onnx"، موفق)
اگر وارونه موفق:
سرچاپ "iris.onnx خوانده نشد:"، مدل.خطا
برگشت ۱
پایان
نام دسته ها := ["setosa"، "versicolor"، "virginica"]
ناپایا ویژگی ها := وکتور {} برگردان وکتور<اعشار۳۲>
هر م در [۵.۱، ۳.۵، ۱.۴، ۰.۲، ۶.۷، ۳.۰، ۵.۲، ۲.۳]:
ویژگی ها.بیفزا(م برگردان اعشار۳۲)
پایان
ناپایا شکل := تانسور.شکل دو(۲، ۴)
ناپایا خوراک ها := وکتور {} برگردان وکتور<تانسور.تانسور>
خوراک ها.بیفزا(تانسور.از آرایه(شکل، ویژگی ها))
خروجی ها := اونیکس.اجرا(مدل، خوراک ها، موفق)
اگر وارونه موفق:
سرچاپ "مدل اجرا نشد:"، مدل.خطا
برگشت ۱
پایان
ناپایا احتمال ها := تانسور.بیشینه نرم(خروجی ها.بگیر(۰))
بهترین := تانسور.نمایه بیشینه محور(احتمال ها، ۱، نادرست)
تکرار ۲ در ی:
سرچاپ "گل"، ی، "از گونهی"، نام دسته ها[بهترین.عنصر(ی) برگردان صحیح] + " است"
پایان
مدل.آزادسازی()
پایانتنظیم dynamic_axes است که اجازه میدهد اندازهی دسته تغییر کند: بدون آن ممکن است PyTorch اندازهی دستهی ۱ را به شکل ثابت در گرههای Reshape و Expand بنویسد و دستهی دوتایی درون گراف شکست بخورد. باید همان پیشپردازشی را به مدل بدهید که با آن آموزش دیده، اینجا اندازههای خام به سانتیمتر.
گونهها
ویژگی Attr
ساختار ویژگی| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نام | name | رشته = "" | نام. |
| گونه | kind | صحیح = 0 | گونهی مقدار در قالب ONNX: ۱ اعشاری، ۲ صحیح، ۳ رشته، ۴ تانسور، ۶ و ۷ فهرست. |
| مقدار اعشاری | f | اعشار۶۴ = 0 | مقدار اعشاری. |
| مقدار صحیح | i | صحیح۶۴ = 0 | مقدار صحیح. |
| مقدار رشته | s | رشته = "" | مقدار رشته. |
| مقدار تانسور | t | تانسور.تانسور | مقدار تانسور. |
| فهرست اعشاری | floats | وکتور<اعشار۶۴> | فهرست اعشاری. |
| فهرست صحیح | ints | وکتور<صحیح۶۴> | فهرست صحیح. |
واردسازی هوش مصنوعی.اونیکس
واردسازی هوش مصنوعی.تانسور
واردسازی فشرده سازی
واردسازی کدگذاری.پروتوباف
واردسازی بایگانی
واردسازی سیستم عامل
تابع زیرپیام(ب &: فشرده سازی.بافر بایت، شماره: صحیح، پیام: فشرده سازی.بافر بایت):
پروتوباف.نوشتن برچسب(ب، شماره، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن بایتهای طولدار(ب، پیام.داده، فشرده سازی.طول بافر(پیام))
پایان
تابع متن(ب &: فشرده سازی.بافر بایت، شماره: صحیح، مقدار: رشته):
پروتوباف.نوشتن برچسب(ب، شماره، پروتوباف.نوع سیم طولدار)
پروتوباف.نوشتن رشته طولدار(ب، مقدار)
پایان
تابع عدد(ب &: فشرده سازی.بافر بایت، شماره: صحیح، مقدار: صحیح۶۴):
پروتوباف.نوشتن برچسب(ب، شماره، پروتوباف.نوع سیم متغیر)
پروتوباف.نوشتن عدد متغیر(ب، مقدار برگردان طبیعی۶۴)
پایان
تابع گره(ب &: فشرده سازی.بافر بایت، عملگر: رشته، ورودی۱: رشته، ورودی۲: رشته، خروجی: رشته):
متن(ب، ۱، ورودی۱)
اگر ورودی۲ != "":
متن(ب، ۱، ورودی۲)
پایان
متن(ب، ۲، خروجی)
متن(ب، ۴، عملگر)
پایان
تابع مدل(م &: فشرده سازی.بافر بایت):
ناپایا گراف := فشرده سازی.بافر بایت جدید()
ناپایا ضرب := فشرده سازی.بافر بایت جدید()
گره(ضرب، "Mul"، "x"، "w"، "h")
زیرپیام(گراف، ۱، ضرب)
ناپایا رلو := فشرده سازی.بافر بایت جدید()
گره(رلو، "LeakyRelu"، "h"، ""، "y")
ناپایا آلفا := فشرده سازی.بافر بایت جدید()
متن(آلفا، ۱، "alpha")
عدد(آلفا، ۲۰، ۱)
پروتوباف.نوشتن برچسب(آلفا، ۲، پروتوباف.نوع سیم ثابت۳۲)
پروتوباف.نوشتن اعشار۳۲(آلفا، ۰.۱)
زیرپیام(رلو، ۵، آلفا)
زیرپیام(گراف، ۱، رلو)
ناپایا وزن := فشرده سازی.بافر بایت جدید()
عدد(وزن، ۱، ۳)
عدد(وزن، ۲، ۱)
ناپایا داده := فشرده سازی.بافر بایت جدید()
هر ضریب در [۲.۰، ۲.۰، ۲.۰]:
پروتوباف.نوشتن اعشار۳۲(داده، ضریب)
پایان
زیرپیام(وزن، ۴، داده)
متن(وزن، ۸، "w")
زیرپیام(گراف، ۵، وزن)
ناپایا ورودی ایکس := فشرده سازی.بافر بایت جدید()
متن(ورودی ایکس، ۱، "x")
زیرپیام(گراف، ۱۱، ورودی ایکس)
ناپایا خروجی وای := فشرده سازی.بافر بایت جدید()
متن(خروجی وای، ۱، "y")
زیرپیام(گراف، ۱۲، خروجی وای)
عدد(م، ۱، ۸)
زیرپیام(م، ۷، گراف)
پایان
تابع ریشه:
ناپایا بافر := فشرده سازی.بافر بایت جدید()
مدل(بافر)
ناپایا سالم := نادرست
ناپایا م := اونیکس.تجزیه اونیکس(بافر.داده، فشرده سازی.طول بافر(بافر)، سالم)
سرچاپ سالم، م.موفق، م.نسخه آی آر، م.گرهها.طول()، م.وزنهای ثابت.طول()، م.نام وزنهای ثابت.دریافت(۰)
ناپایا رلو := م.گرهها.دریافت(۱)
سرچاپ رلو.عملگر، رلو.ورودیها.دریافت(۰)، رلو.خروجیها.دریافت(۰)، رلو.نمایه ویژگی("alpha")
سرچاپ (رلو.ویژگی اعشاری("alpha"، ۰.۰) * ۱۰۰.۰ + ۰.۵) برگردان صحیح، رلو.ویژگی صحیح("axis"، -۱)
ویژگی := رلو.ویژگیها.دریافت(۰)
سرچاپ ویژگی.نام، ویژگی.گونه
سرچاپ م.نام ورودیها().طول()، م.ورودیها.دریافت(۰)، م.خروجیها.دریافت(۰)
ناپایا شکل := تانسور.شکل دو(۱، ۳)
ناپایا ایکس := تانسور.پرشده(شکل، -۱.۵)
ایکس.تنظیم در(۲، ۴.۰)
ناپایا ورودیها := وکتور {} برگردان وکتور<تانسور.تانسور>
ورودیها.بیفزا(ایکس)
ناپایا خروجیها := اونیکس.اجرا(م، ورودیها، سالم)
ناپایا وای := خروجیها.دریافت(۰)
سرچاپ سالم، (وای.عنصر(۰) * ۱۰۰.۰ - ۰.۵) برگردان صحیح، وای.عنصر(۲)
مسیر := سیستم عامل.پوشه موقت() + "/salam_tiny.onnx"
_ := بایگانی.نوشتن پرونده دودویی از بافر(مسیر، بافر)
ناپایا م۲ := اونیکس.بارگذاری اونیکس(مسیر، سالم)
سرچاپ سالم، م۲.گرهها.طول()
م۲.آزادسازی()
م.آزادسازی()
فشرده سازی.آزادسازی بافر(بافر)
پایانآزادسازی free
تابع آزادسازی()نمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
گره Node
ساختار گره| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| عملگر | op | رشته = "" | نام عملگر، مثل Gemm یا Relu. |
| نام | name | رشته = "" | نام گره. |
| ورودیها | inputs | وکتور<رشته> | نام ورودیها. |
| خروجیها | outputs | وکتور<رشته> | نام خروجیها. |
| ویژگیها | attrs | وکتور<ویژگی> | ویژگیها. |
نمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
نمایه ویژگی attr_index
تابع نمایه ویژگی(name: رشته): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
ویژگی صحیح attr_int
تابع ویژگی صحیح(name: رشته، dflt: صحیح۶۴): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
ویژگی اعشاری attr_float
تابع ویژگی اعشاری(name: رشته، dflt: اعشار۶۴): اعشار۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
آزادسازی free
تابع آزادسازی()نمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
مدل Model
ساختار مدل| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| ورودیها | inputs | وکتور<رشته> | نام ورودیهای گراف. |
| خروجیها | outputs | وکتور<رشته> | نام خروجیها. |
| گرهها | nodes | وکتور<گره> | گرهها به ترتیب اجرا. |
| نام وزنهای ثابت | init_names | وکتور<رشته> | نام وزنهای ثابت. |
| وزنهای ثابت | inits | وکتور<تانسور.تانسور> | وزنهای ثابت. |
| نسخه آی آر | ir_version | صحیح۶۴ = 0 | نسخهی IR در پرونده. |
| خطا | error | رشته = "" | پیام خطا. |
| موفق | ok | منطقی = نادرست | درست خوانده شد. |
نمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
نام ورودیها feed_names
تابع نام ورودیها(): وکتور<رشته>اجرا بدهید.نمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
آزادسازی free
تابع آزادسازی()نمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
تابعها
تجزیه اونیکس ParseOnnx
تابع تجزیه اونیکس(p: تهی*، n: صحیح، ok &: منطقی): مدلنمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
بارگذاری اونیکس LoadOnnx
تابع بارگذاری اونیکس(path: رشته، ok &: منطقی): مدل.onnx میخواند. وزنهایی که در پروندهی دادهی بیرونی ذخیره شدهاند پشتیبانی نمیشوند.نمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam
اجرا Run
تابع اجرا(model &: مدل، inputs &: وکتور<تانسور.تانسور>، ok &: منطقی): وکتور<تانسور.تانسور>نام ورودیها یک تانسور، و خروجیها را به ترتیب خروجیهای گراف برمیگرداند. در صورت شکست ok نادرست، فهرست خالی و error مدل نام عملگر شکستخورده را دارد.نمونهی این مورد همراه با موارد بالاتر آمده است: ai-onnx-Run.salam