پالت فرمان

دنبال فرمانی برای اجرا بگردید…

ZarynZaryn
امکانات Zaryn·۹ دقیقه مطالعه

ارزیابی‌ها و تبار

تغییر دادن کد آسان است؛ دانستن اینکه چیزی بدتر نشده سخت است. یک وابستگی تازه ۴۰ KiB به باندل اضافه می‌کند، یک بازنویسی حلقهٔ اصلی را ۱۵٪ کندتر می‌کند، تغییر یک درایور فرم‌ور را از ظرفیت فلش بیرون می‌زند، یک شیدر نرخ فریم را پایین می‌آورد، تغییر بارگذار داده دو درصد دقت را از بین می‌برد. معمولاً هفته‌ها بعد کسی متوجه هرکدام می‌شود. در Zaryn عددهای هر کامیت نگه داشته می‌شود، و درخواست ادغامی که یکی از آن‌ها را بدتر کند ادغام نمی‌شود. برای هر پروژه‌ای کار می‌کند: برنامه‌های وب، بازی‌ها، فرم‌ور سیستم‌های نهفته، Rust، Zig، C/C++، Go، Python و یادگیری ماشین. دو فرمان لازم دارید. ## ۱. بگذارید zev پروژه را بررسی کند یک بار، در مخزنتان: ```bash zev eval init ``` zev نوع پروژه را تشخیص می‌دهد و `zev-evals.json` را می‌نویسد: چه اجرا شود، زمان چه چیزی سنجیده شود و اندازهٔ کدام فایل‌ها اندازه‌گیری شود. برای یک پروژهٔ Rust: ```json { "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` | مدلی را آموزش می‌دهید یا ارزیابی می‌کنید؟ از فرمان خودتان شروع کنید: ```bash zev eval init -- python eval.py ``` ## ۲. پیش از هر درخواست ادغام اجرایش کنید ```bash zev eval run ``` ```text $ cargo build --release build_time: 41.25 s $ cargo test ... finished in 3.10 s Found 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` مقایسه کرد و همین حالا، نه بعد از بازبینی، گفت که این تغییر فایل اجرایی را ۱۲٪ بزرگ‌تر می‌کند. - **هنوز push نکرده‌اید؟** فقط بررسی است و چیزی ذخیره نمی‌شود. push کنید و دوباره اجرا کنید (یا بگذارید CI اجرا کند) تا نتایج برای آن کامیت ثبت شود. - **push کرده‌اید؟** نتایج ثبت می‌شوند و در زبانهٔ **Evals & lineage** مخزن دیده می‌شوند. - **روی خود `main`؟** کامیت با اجرای قبلی مقایسه می‌شود. - اگر معیاری بدتر شود `zev eval run` با کد ۱ خارج می‌شود، پس در CI هم کار می‌کند. برای ثبت بدون شکست، `--no-fail` را اضافه کنید. - `--dry-run` فقط بررسی می‌کند و حتی برای کامیتِ push‌شده چیزی ذخیره نمی‌کند. ## zev چه چیزهایی را می‌خواند چیز خاصی لازم نیست: 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`: ```json "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`، با واحد خودش. با کلیک روی هر معیار نموداری باز می‌شود که هر نقطه‌اش کامیت خودش را باز می‌کند، به‌همراه بهترین مقدار، بزرگ‌ترین افت و کامیتی که باعثش شد، و یک حد مجاز پیشنهادی. اجراهای شاخه‌های دیگر با یک کلیک دیده می‌شوند. - **مقایسه**: هر دو کامیت یا شاخه، معیار به معیار، با نتیجه‌ای که یک درخواست ادغام میان آن‌ها می‌گرفت. - **درخواست‌های ادغام**: هر درخواست ادغام بررسی ارزیابی خودش را نشان می‌دهد. بدتر شدن جلوی ادغام را می‌گیرد تا وقتی درست شود، حد مجاز عوض شود، یا کسی که ادغام می‌کند بررسی را نادیده بگیرد. ## نشان برای README ```bash zev eval badge binary ``` Markdownی را چاپ می‌کند که در README می‌گذارید؛ نشان به زبانهٔ **Evals & lineage** پیوند دارد. آخرین مقدار معیار روی `main` را با واحدش نشان می‌دهد (`4.31 MiB`، `92.4%`، `58.2 fps`): سبز تا وقتی ثابت مانده، قرمز وقتی آخرین تغییر بدترش کرده. نشانِ مخزن‌های خصوصی به کسانی که به مخزن دسترسی ندارند چیزی نشان نمی‌دهد. ## مقایسهٔ هر دو نسخه ```bash zev eval # این کامیت در کنار main zev eval show v2-experiment # یک شاخه یا کامیت در کنار main zev eval compare v1 v2 # هر دو نسخه zev eval compare main --json # برای اسکریپت‌ها ``` ## در CI هر CI که بتواند فرمان shell اجرا کند کافی است. توکنی از **تنظیمات** را به‌عنوان secret نگه دارید، سپس: ```bash curl -fsSL https://zaryn.xyz/install.sh | sh export ZEV_SERVER=zaryn.xyz ZEV_TOKEN=$ZARYN_TOKEN zev clone you/app@$BRANCH && cd app zev eval run ``` نتایج هر push ثبت می‌شود، و وقتی درخواست ادغام به‌هرحال مسدود می‌شد کار CI شکست می‌خورد، پس همان‌جا می‌بینیدش. در مرحلهٔ قبل JUnit XML یا lcov می‌سازید؟ `zev eval report junit.xml lcov.info` آن‌ها را گزارش می‌کند. بدون zev، عددها را خودتان بفرستید: ```bash 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>` دو نسخه را مقایسه می‌کند. ## تبار: از کجا آمده ثبت کنید این مخزن از چه ساخته شده: ```bash zev lineage record trained_on you/imagenet-mini zev 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** همه خبر می‌دهند: نتایج ممکن است کهنه باشند؛ دوباره آموزش دهید یا ارزیابی را دوباره اجرا کنید، سپس پیوند را دوباره ثبت کنید. ```text ⚠ Trained on you/imagenet-mini has changed since (recorded at c4f51a25cd, its main is now a023c62c92); these results may be stale. ``` - **وقتی چیزی در بالادست آلوده می‌شود.** یک [هشدار](/docs/fa/advisories) که علیه مجموعه‌داده‌ای مسموم یا مدل پایه‌ای با در پشتی ثبت شود، به همهٔ مدل‌هایی می‌رسد که ساخته‌شده از آن ثبت شده‌اند، و به مالکانشان خبر داده می‌شود. برای مدلی که وزن‌هایش در Zaryn است، این زبانه می‌تواند با مقایسهٔ وزن‌ها مدل پایه‌ای را که از آن تنظیم دقیق شده پیشنهاد کند. با یک کلیک ثبتش کنید. ## خوب است بدانید - نتایج در همهٔ طرح‌ها رایگان‌اند. گراف چندمرحله‌ای تبار (مجموعه‌داده‌ها ← مدل‌های پایه ← تنظیم‌های دقیق ← عامل‌ها) بخشی از Premium است؛ پیوندهای مستقیم رایگان‌اند. - معیارها در **مجموعه‌ها** (suite) گروه می‌شوند (`--suite`، پیش‌فرض `default`) تا یک مخزن بتواند چند بنچمارک یا سخت‌افزار هدف را جدا نگه دارد (مثلاً `esp32` و `rp2040`). - ثبت نتایج به دسترسی نوشتن در مخزن نیاز دارد. خواندن و مقایسه دسترسی خواندن می‌خواهد. - `zev metrics`، `zev check` و `zev history` عددها را فقط در مخزن محلی شما نگه می‌دارند؛ `zev eval` است که آن‌ها را در Zaryn به اشتراک می‌گذارد و جلوی درخواست‌های ادغام را می‌گیرد.