فایل safetensors را فقط از روی نام و پسوند تأیید نکنید. سرآیند باید نوع و شکل هر tensor را با بازهٔ درستِ داده سازگار توصیف کند. در تمرین این صفحه، یک فایل بسیار کوچک و اصیل با دو tensor میسازیم؛ بازرس محلی تعداد بایت مورد انتظار را با offsetها مقایسه میکند. این بازرس زیرمجموعهای آموزشی است؛ مدل، Torch یا کتابخانهٔ safetensors بارگذاری نمیشود.
سه بخش فایل را جدا بخوانیم
طبق بخش Format در مخزن اصلی، هشت بایت نخست طول سرآیند را بهصورت عدد صحیحِ بدون علامتِ little-endian نگه میدارند. سپس همان تعداد بایتِ JSON با UTF-8 و بعد buffer داده قرار میگیرد. offsetهای tensor نسبت به آغاز buffer داده هستند؛ آنها را مستقیم از ابتدای فایل نبُرید.
در فایل ساختهشده، سرآیند ۱۴۵ بایت و داده ۱۶ بایت است. پس buffer از offset مطلق ۱۵۳ شروع میشود: هشت بایتِ طول، بهاضافهٔ ۱۴۵ بایتِ سرآیند. این عدد مخصوص همین JSON است؛ با تغییر نام یا فراداده، طول سرآیند میتواند عوض شود. کد آن را از همان بایتهای فایل میخواند و حدس ثابت نمیزند.
شکل و dtype باید به اندازه برسند
tensor اول با نام a از نوع F32 و شکل [2] است؛ دو عضوِ چهاربایتی، هشت بایت میخواهند. tensor دوم b از نوع I64 و شکل [1] یک عضوِ هشتبایتی دارد. محتوای اصیل بهترتیب ۱٫۵، منفیِ۲ و عدد صحیحِ۳ است؛ بازکردن همین مقدارهای معلوم با struct نیز جدا با انتظار مقایسه میشود.
| tensor | بازهٔ نسبی، پایان غیرشامل | بازهٔ مطلق در فایل نمونه |
|---|---|---|
| a؛ F32 و [2] | [0,8) | [153,161) |
| b؛ I64 و [1] | [8,16) | [161,169) |
END اولین بایتِ بعد از بخش است؛ طول را با END−BEGIN میگیریم. این قرارداد با بازهٔ HTTP دارای انتهای شامل فرق دارد. اگر shape را [3] کنیم اما همان هشت بایت بماند، descriptor دیگر اندازهٔ لازم را توضیح نمیدهد و تمرین آن را رد میکند.
همپوشانی و حفره را کنترل کنیم
در بازرس، همهٔ بازههای دارای داده مرتب میشوند. شروع نخست باید صفر باشد، آغاز هر بازه به پایان قبلی برسد و پایان آخر برابر طول buffer شود. بنابراین دو tensor نمیتوانند در این زیرمجموعه روی یک ناحیه بیفتند یا بایتِ بیصاحب در وسط و انتها باقی بگذارند. این کنترل، صحت معنای وزنهای مدل را نمیسنجد.
هشت مورد ناسازگار واقعاً اجرا و رد میشوند: شکلِ ناهماهنگ، همپوشانی، حفره، offset بیرونِ buffer، مقدار غیررشتهای در metadata، dtype خارج از پشتیبانی، کلید JSON تکراری و سرآیندِ ناقص. parser با object_pairs_hook تکرار کلید را پیش از محوشدن در dict پیدا میکند؛ پیام موفقِ json.loads بهتنهایی کافی نیست.
اسکالر و tensor خالی را گم نکنیم
shape برابر [] در نمونهٔ جدا یک اسکالر با یک عضو است؛ حاصلضربِ ابعادِ فهرست خالی را صفر فرض نمیکنیم. یک اسکالر I64 با مقدارِ۷، هشت بایت دارد. در مقابل، shape برابر [0,3] صفر عضو و بازهٔ [0,0) دارد؛ metadata شکل هنوز وجود دارد اما دادهای ذخیره نشده است.
این دو حالت جدا اجرا شدهاند. بازهٔ صفرطول را با هشت بایت padding یا مقدارِ عددیِ صفر یکی نگیریم. ابزار دربارهٔ کیفیت مدلِ دارای tensor خالی یا پشتیبانی یک loader خاص تصمیم نمیدهد؛ فقط قرارداد اندازهٔ همان نمونه را کنترل میکند.
حدود بازرس را کنار خروجی بگذاریم
dtypeهای این کد فقط F32 و I64 هستند؛ نامها نیز از زیرمجموعهٔ ASCII اعلامی میآیند. سقف سرآیند ۴۰۹۶ بایت، داده ۸۱۹۲ بایت، هشت بُعد و ۱۰۲۴ عضو است. این حدها انتخاب تمریناند و سقف عمومی safetensors یا ظرفیت مدلهای اپرا نیستند. نامعتبر بودن در این parser ممکن است فقط به معنی خارجبودن از زیرمجموعه باشد.
نسخهٔ Python اجرا ۳٫۱۲٫۱۴ است. هیچ فایل ناشناس یا مدل دانلودی خوانده نشده؛ فایل نمونه در حافظه ساخته میشود و hex آن در نتیجه وجود دارد. بررسی ساختار نیز اصالت ناشر، مجوز، نبودِ NaN در مقدار tensor یا بیخطر بودن همهٔ مسیرهای loader را ثابت نمیکند. منبع اصلی هم بررسی مقدارهای tensor را با توصیف ظرف یکی نمیداند.
از ظرفِ سالم تا اجرای درست
راهنمای سازگاری فایل مدل معماری، توکنایزر و اجراکننده را ادامه میدهد؛ بررسی منبع و هش دانلود نیز شاهد اصالت را از هش محلی جدا میکند. سالمبودن offsetها جای هیچکدام را نمیگیرد.
برای ادامه در مبانی هوش مصنوعی، نسخهٔ قالب و قراردادِ تحویل بسته را ثبت کنید. این راهنما عرضهٔ زیرساختِ مدل محلی یا امکان بازکردن safetensors در محصول اپرا را اعلام نمیکند؛ خروجی مفیدش یک بازرس کوچک و قابل تکرار برای تفکیکِ خطای ظرف از مراحل بعدی است.
فایل تمرین و منبع
کد کامل تمرینِ محلی و کنترلهای آن · نمونههای اصیل و نتیجهٔ اجرای واقعیِ همین کد
منابع در 2026-11-04 خوانده شدند؛ این تاریخ، تاریخ انتشار منبع نیست. مثالها و فایلهای این راهنما آموزشی و ساختهٔ تحریریهاند.