دنبال فرمانی برای اجرا بگردید…
تغییر دادن کد آسان است؛ دانستن اینکه چیزی بدتر نشده سخت است. یک وابستگی تازه ۴۰ KiB به باندل اضافه میکند، یک بازنویسی حلقهٔ اصلی را ۱۵٪ کندتر میکند، تغییر یک درایور فرمور را از ظرفیت فلش بیرون میزند، یک شیدر نرخ فریم را پایین میآورد، تغییر بارگذار داده دو درصد دقت را از بین میبرد. معمولاً هفتهها بعد کسی متوجه هرکدام میشود. در Zaryn عددهای هر کامیت نگه داشته میشود، و درخواست ادغامی که یکی از آنها را بدتر کند ادغام نمیشود.
برای هر پروژهای کار میکند: برنامههای وب، بازیها، فرمور سیستمهای نهفته، Rust، Zig، C/C++، Go، Python و یادگیری ماشین. دو فرمان لازم دارید.
یک بار، در مخزنتان:
zev eval initzev نوع پروژه را تشخیص میدهد و zev-evals.json را مینویسد: چه اجرا شود، زمان چه چیزی سنجیده شود و اندازهٔ کدام فایلها اندازهگیری شود. برای یک پروژهٔ Rust:
{ "command": "cargo test", "time": { "build_time": "cargo build --release" }, "files": { "binary": "target/release/app" }, "base": "main"}command اجرا میشود و خروجیاش برای نتیجهٔ تستها، پوشش کد و بنچمارکها خوانده میشود. میتواند یک فهرست باشد.time زمان هر فرمان را میسنجد (اگر "repeat" بگذارید، میانهٔ چند اجرا: {"run": "...", "repeat": 5}).files پس از اجرای فرمانها اندازهها را میسنجد. مسیر میتواند الگو باشد (dist/**/*.js)، و "gzip": true اندازهٔ فشرده را هم ثبت میکند.آن را کامیت کنید. از این پس شما، تیمتان و CI همگی همان بررسیها را اجرا میکنید.
آنچه zev eval init آماده میکند:
| پروژه | آنچه دنبال میشود |
|---|---|
Rust (Cargo.toml) | نتیجهٔ cargo test، زمان ساخت release، اندازهٔ فایل اجرایی؛ بنچمارکهای Criterion |
JavaScript / TypeScript (package.json) | نتیجهٔ npm test، زمان ساخت، اندازهٔ باندل و اندازهٔ فشردهاش با gzip |
Go (go.mod) | نتیجهٔ go test، مقدار ns/op و B/op و allocs/op هر بنچمارک، پوشش کد، زمان ساخت |
Zig (build.zig) | نتیجهٔ zig build test، زمان ساخت ReleaseFast، اندازهٔ فایل اجرایی |
C / C++ (CMakeLists.txt) | نتیجهٔ ctest، زمان ساخت release؛ فایل اجراییتان را زیر files بیاورید |
سیستمهای نهفته (platformio.ini) | مصرف RAM و Flash از pio run |
Godot (project.godot)، Unity | زمان خروجی گرفتن و اندازهٔ بیلد |
Python (pyproject.toml) | نتیجهٔ pytest |
هر پروژه با Makefile | نتیجهٔ make test |
مدلی را آموزش میدهید یا ارزیابی میکنید؟ از فرمان خودتان شروع کنید:
zev eval init -- python eval.pyzev eval run$ cargo build --release build_time: 41.25 s$ cargo test... finished in 3.10 sFound 4 metrics in 1 timing, its output, 1 file size METRIC main fb6a20769d this commit CHANGE build_time 40.80 s 41.25 s +450.00 ms (+1.1%) = held tests.passed 212 214 +2 ✓ better tests.failed 0 0 +0 = held (lower is better) binary 3.84 MiB 4.31 MiB +481.3 KiB (+12.2%) ✗ worse than ±1%✗ A pull request into main would be blocked: binaryهمهٔ چرخه همین است. zev تستها و ساخت را اجرا کرد، با main مقایسه کرد و همین حالا، نه بعد از بازبینی، گفت که این تغییر فایل اجرایی را ۱۲٪ بزرگتر میکند.
main؟ کامیت با اجرای قبلی مقایسه میشود.zev eval run با کد ۱ خارج میشود، پس در CI هم کار میکند. برای ثبت بدون شکست، --no-fail را اضافه کنید.--dry-run فقط بررسی میکند و حتی برای کامیتِ pushشده چیزی ذخیره نمیکند.چیز خاصی لازم نیست: zev همان چیزی را میخواند که ابزارهایتان از قبل چاپ میکنند یا مینویسند. آنها را در command اجرا کنید، یا فایلی را که دارید با zev eval report <file>... گزارش کنید، یا نامش را زیر "results" در zev-evals.json بیاورید.
| نوع | از کجا خوانده میشود |
|---|---|
| نتیجهٔ تستها | cargo، pytest، jest، vitest، zig build test --summary all، ctest، go test؛ JUnit XML از هر زبانی |
| پوشش کد | go test -cover، lcov، Cobertura، JaCoCo، istanbul (coverage-summary.json)، llvm-cov |
| بنچمارکها | Criterion، بنچمارکهای Go، Google Benchmark، hyperfine، pytest-benchmark، vitest bench |
| وب | Lighthouse، size-limit، k6 |
| سیستمهای نهفته | RAM و Flash در PlatformIO، GNU size (flash = text + data و RAM = data + bss)، اندازهٔ ESP-IDF |
| عددهای خودتان | یک شیء JSON (آخرینش حساب میشود)، یا خطهای name: value / name=value با واحد: frame_ms_p99: 18.2ms، load_time: 2.5s، heap: 48 MB، avg_fps: 58.2، accuracy: 91.2% |
| یادگیری ماشین | نتایج lm-evaluation-harness (hellaswag.acc، بدون stderr)، فایلهای Hugging Face Trainer (eval_accuracy، eval_loss) |
هر معیار واحد خودش را نگه میدارد. زمانها به میلیثانیه و اندازهها به بایت ذخیره میشوند، و همانطور که میخوانیدشان نشان داده میشوند (2.91 µs، 356.0 KiB، 58.2 fps). zev جهت درست هرکدام را میداند: زمان، اندازه، حافظه، خطاها، شکستها، loss و تأخیر پایین؛ تستهای موفق، پوشش کد، fps و دقت بالا. شمارندههایی مثل epoch، step، seed و samples_per_second معیار کیفیت نیستند و کنار گذاشته میشوند، مگر اینکه در "metrics" نامشان را بیاورید. --only a,b فقط همینها را گزارش میکند، و --lower a,b معیارهایی را مشخص میکند که کمترشان بهتر است.
دو اجرا بهندرت دقیقاً یک عدد میدهند. حد مجاز یک معیار بیشترین تغییر رو به بدتر است که هنوز «ثابت» حساب میشود، یا به واحد خود معیار یا بهصورت درصدی از مقدار main:
"metrics": { "build_time": { "tolerance": "15%" }, "binary": { "tolerance": "2%" }, "accuracy": { "tolerance": 0.005 }, "tests.failed": { "tolerance": 0 }}پیشفرضهایی که به بیشتر پروژهها میخورد: زمانها ۱۰٪، اندازهها ۱٪، پوشش کد ۰٫۵ واحد درصد، و بقیه ۰ (هر افتی حساب میشود). "tolerance" در سطح بالا برای همهٔ معیارهاست؛ --tolerance 5% آن را برای یک اجرا تغییر میدهد. مطمئن نیستید چه عددی بگذارید؟ در زبانهٔ Evals & lineage روی معیار کلیک کنید: نشان میدهد معیار بین اجراها معمولاً چقدر جابهجا میشود و یک حد مجاز پیشنهاد میکند.
زمانسنجی در CI پرنوسانتر از رایانهٔ خودتان است. به فرمانهای کند "repeat": 3 یا ۵ بدهید (میانه حساب میشود)، و اگر اجراکنندهها مشترکاند حد مجاز بازتری بگذارید.
برنامهٔ وبی که باید سبک بماند. zev eval init در یک پروژهٔ Vite، Next یا npm ساده نتیجهٔ تستها، زمان ساخت و اندازهٔ dist/**/*.js و .css را، فشرده با gzip هم، دنبال میکند. درخواست ادغامی که یک کتابخانهٔ ۵۰ KiB را به باندل ۲۰۰ KiB اضافه کند با حد ۱٪ مسدود میشود؛ JSON خروجی Lighthouse را زیر "results" بیاورید تا امتیازهای کارایی هم دنبال شوند.
فرموری که باید جا شود. با PlatformIO، pio run از قبل RAM و Flash را چاپ میکند و zev هر دو را دنبال میکند. با یک toolchain ساده، arm-none-eabi-size build/fw.elf را در command بگذارید. تغییری که فرمور را چند صد بایت بزرگتر کند پیش از رسیدن به دستگاه دیده میشود.
بازیای که باید روان بماند. یک صحنهٔ بنچمارک را بدون نمایشگر اجرا کنید و چند خط چاپ کنید (avg_fps: 58.2، frame_ms_p99: 21.4ms، load_time: 2.5s)؛ خروجی گرفتن Godot یا Unity را زیر "time" و پوشهٔ بیلد را زیر "files" بیاورید.
کتابخانهای که باید سریع بماند. Criterion، بنچمارکهای Go، Google Benchmark یا hyperfine: هر بنچمارک با واحد زمانیاش یک معیار میشود. برای زمان کل فرمانها "repeat" را اضافه کنید.
مدلی که باید دقیق بماند. zev eval init -- python eval.py. امتیازها را بهصورت JSON ({"accuracy": 0.912, "f1": 0.88}) یا خطهای name: value چاپ کنید، یا "results" را به خروجی lm-evaluation-harness یا Hugging Face بدهید.
زبانهٔ Evals & lineage مخزن اینها را نشان میدهد:
main، با واحد خودش. با کلیک روی هر معیار نموداری باز میشود که هر نقطهاش کامیت خودش را باز میکند، بههمراه بهترین مقدار، بزرگترین افت و کامیتی که باعثش شد، و یک حد مجاز پیشنهادی. اجراهای شاخههای دیگر با یک کلیک دیده میشوند.zev eval badge binaryMarkdownی را چاپ میکند که در README میگذارید؛ نشان به زبانهٔ Evals & lineage پیوند دارد. آخرین مقدار معیار روی main را با واحدش نشان میدهد (4.31 MiB، 92.4%، 58.2 fps): سبز تا وقتی ثابت مانده، قرمز وقتی آخرین تغییر بدترش کرده. نشانِ مخزنهای خصوصی به کسانی که به مخزن دسترسی ندارند چیزی نشان نمیدهد.
zev eval # این کامیت در کنار mainzev eval show v2-experiment # یک شاخه یا کامیت در کنار mainzev eval compare v1 v2 # هر دو نسخهzev eval compare main --json # برای اسکریپتهاهر CI که بتواند فرمان shell اجرا کند کافی است. توکنی از تنظیمات را بهعنوان secret نگه دارید، سپس:
curl -fsSL https://zaryn.xyz/install.sh | shexport ZEV_SERVER=zaryn.xyz ZEV_TOKEN=$ZARYN_TOKENzev clone you/app@$BRANCH && cd appzev eval runنتایج هر push ثبت میشود، و وقتی درخواست ادغام بههرحال مسدود میشد کار CI شکست میخورد، پس همانجا میبینیدش. در مرحلهٔ قبل JUnit XML یا lcov میسازید؟ zev eval report junit.xml lcov.info آنها را گزارش میکند.
بدون zev، عددها را خودتان بفرستید:
curl -X POST https://zaryn.xyz/api/v1/repos/you/app/evals \ -H "Authorization: Bearer $ZEV_TOKEN" -H "Content-Type: application/json" \ -d '{"commit_hash":"main","metrics":[ {"name":"build_time","value":41250,"unit":"ms","higher_is_better":false,"tolerance":"10%"}, {"name":"accuracy","value":0.912,"tolerance":0.005}]}'unit یکی از ms، bytes، % یا fps است، یا برای عدد ساده حذف میشود؛ tolerance به واحد معیار است یا درصدی مثل "10%". پاسخ شامل بررسی در برابر main است. POST /v1/repos/<owner>/<repo>/evals/compare با همان metrics بدون ذخیرهٔ چیزی بررسی میکند (دسترسی خواندن کافی است). GET .../evals/compare?base=main&head=<commit or branch> دو نسخه را مقایسه میکند.
ثبت کنید این مخزن از چه ساخته شده:
zev lineage record trained_on you/imagenet-minizev lineage record fine_tuned_from meta/llama-3-8b@<commit>رابطهها: trained_on، fine_tuned_from، evaluated_on، derived_from (مجموعهدادهای که از دیگری پاکسازی یا برچسبگذاری شده، یا انشعابی از یک پروژه) و uses (برنامهای که به یک مدل، کتابخانه یا بستهٔ دارایی وابسته است). کامیت فعلی منبع ثبت میشود، یا کامیتی که بعد از @ میآید.
تبار دو بار به کار میآید:
وقتی داده تغییر میکند. اگر you/imagenet-mini بعد از آموزش مدل شما کامیتهای تازه بگیرد، zev lineage upstream، zev eval run و زبانهٔ Evals & lineage همه خبر میدهند: نتایج ممکن است کهنه باشند؛ دوباره آموزش دهید یا ارزیابی را دوباره اجرا کنید، سپس پیوند را دوباره ثبت کنید.
⚠ Trained on you/imagenet-mini has changed since (recorded at c4f51a25cd, its main is now a023c62c92); these results may be stale.وقتی چیزی در بالادست آلوده میشود. یک هشدار که علیه مجموعهدادهای مسموم یا مدل پایهای با در پشتی ثبت شود، به همهٔ مدلهایی میرسد که ساختهشده از آن ثبت شدهاند، و به مالکانشان خبر داده میشود.
برای مدلی که وزنهایش در Zaryn است، این زبانه میتواند با مقایسهٔ وزنها مدل پایهای را که از آن تنظیم دقیق شده پیشنهاد کند. با یک کلیک ثبتش کنید.
--suite، پیشفرض default) تا یک مخزن بتواند چند بنچمارک یا سختافزار هدف را جدا نگه دارد (مثلاً esp32 و rp2040).zev metrics، zev check و zev history عددها را فقط در مخزن محلی شما نگه میدارند؛ zev eval است که آنها را در Zaryn به اشتراک میگذارد و جلوی درخواستهای ادغام را میگیرد.