مدلهای هوش مصنوعی میتوانند ویژگیهای کامل را در چند دقیقه تولید کنند، اما آیا کد صحیح است؟ ما Android Bench، معیار ارزیابی هوش مصنوعی خود را، برای پاسخ به این سؤال پساز تجزیهوتحلیل هزاران تغییر کد تولیدشده ساختیم.
این گفتگو بینشهایی را از سفر ما به اشتراک میگذارد، ازجمله تمام راههایی که دیدیم مدلها تقلب میکنند، چگونه ویژگیهای خاص پیامواره منجر به کیفیت بالاتر کد میشود، و چگونه عوامل مختلف به یک وظیفه مشابه نزدیک میشوند.
آوانویسی
Tomáš Mlynarič
صبح بخیر، همگی.
بیایید شروع کنیم.
در ماه مارس، Android Bench را راهاندازی کردیم که مجموعه داده و جدول ردهبندی ما برای اندازهگیری مدلهای زبانی بزرگ در تکالیف توسعه Android است.
از آن زمان، آن را دربرابر بسیاری از مدلهای جدید اجرا کردهایم.
و همین ماه گذشته، Android Bench 2.0 را منتشر کردیم.
اگرچه فقط چند ماه گذشته است، اما در دنیای هوش مصنوعی، این مدت مثل ابدیت بهنظر میرسد.
نام من توماس است و میخواهم سفرمان با Android Bench و اینکه چگونه به جایگاه فعلیمان رسیدیم را با شما همرسانی کنم.
بیایید با ۱.۰ شروع کنیم.
در نسخه ۱.۰، مشکلات دنیای واقعی را از مخازن متنباز گرفتیم.
پروژههای GitHub را با مشکلات GitHub، درخواستهای کشش حلکننده آن مشکلات، و آزمایشهای تأییدکننده راهحلها فیلتر کردیم.
درخواستهای pull را به دستههای تکلیفی برای مدلهای هوش مصنوعی تقسیم میکنیم.
مشکل GitHub به دستورالعملها یا پیامواره مدل تبدیل شد و ما آنها را در وضعیت قبلاز PR قرار دادیم.
و وقتی مدل کاری را ایجاد کرد، آزمایشها را انجام دادیم و آنها را روی خروجی اعمال کردیم که نتیجه قبولی یا ردی را به ما داد.
این تلاش هوش مصنوعی برای حل مسئله را «آزمایش» مینامیم.
و همچنین میتوانیم آن را براساس راهحل ساختهشده توسط انسان از آن PR مقایسه کنیم، یا آن را راهحل طلایی مینامیم.
این روش مشابه محک SWE-bench است که کاملاً شناختهشده است.
با بیشاز ۱۰٬۰۰۰ تکلیف بالقوه شروع کردیم و همه آنها مناسب نبودند.
برخیاز آنها دستورالعملهای ناقص یا بیشازحد مشخص داشتند.
ممکن است آزمایشها با راهحل طلایی جفت شده باشند یا وضعیت قبلاز درخواست بازبینی خراب شده باشد.
بنابراین، مجبور شدیم بارها و بارها مرور کنیم تا به ۱۰۰ تکلیف منصفانه برسیم.
درطول این بازبینیها، از مدلهای پیشرفته برای دریافت برخی نتایج استفاده کردیم.
و با حل حدود ۳۰٪ از تکالیف شروع کردیم که به آن نرخ قبولی میگوییم.
و سپس، وقتی مجموعه داده را برای انتشار رسمی قفل کردیم، مدلهای برتر در حدود ۷۰٪ بودند.
ولی این یعنی یک ماه بعد.
و سپس برنامهای داشتیم که هر ماه مدلهای جدید را ارزیابی کنیم و سپس تماشا کردیم که چگونه آنها بهتر میشوند.
و در نسخه اوت، نرخ قبولی ۹۲٪ برای بهترین مدل بود.
و میدانستیم که سطح ما خیلی پایین است و این مجموعه داده اشباع شده است.
Tomáš Mlynarič
اما ما این را پیشبینی کرده بودیم و از قبل سخت مشغول کار روی نسخه ۲.۰ بودیم که ماه گذشته آن را منتشر کردیم.
هدف این است و بوده که با تکالیف پیچیده و واقعی Android، سطح را ارتقا دهیم و راهنمایی و شفافیت درباره عملکرد LLM برای شما توسعهدهندگان ارائه دهیم، و همچنین سازندگان مدل را تشویق کنیم تا با ارائه یک معیار خوب برای رقابت، Android را در اولویت قرار دهند.
و همچنین ارائه تحلیل و نتایجی که هم به شما و هم به سازندگان مدل کمک میکند.
اما باید هوش، سرسختی، و تقلب را هم درنظر بگیریم.
و باید از خطر آلودگی جلوگیری کنیم.
یکی از مشکلات روش SWE-bench، باز بودن واقعی کد منبع است.
OpenAI مقالهای منتشر کرد.
آنها متوجه شدند که مدلها میتوانند کلمات بعدی دستورالعملها را تکمیل کنند یا میتوانند تکلیفی را با خطایی مبهم که بخشی از دستورالعملها نبود حل کنند.
و متوجه شدند که سازندگان مدل درحال آموزش روی کد منبعباز هستند و SWE-bench آلوده شده است.
بنابراین برای نسخه ۲.۰، درواقع کد را بسته نگه میداریم تا از آموزش روی آن جلوگیری کنیم.
کار را به چهار جریان کاری تقسیم کردیم.
در مورد اول، تبدیل برنامه را انجام میدهیم، که در آن برنامههای متنباز Flutter و React Native را گرفتیم و به عاملها گفتیم آنها را به راهحل Android بومی تبدیل کنند.
این درواقع نشاندهنده روند مهاجرت از چندسکویی به بومی است که اکنون شاهد آن هستیم.
جریان کاری دوم ویژگیهای جدید و ادغامهای پلاتفرم بود.
آنها در پایگاههای کد تولیدی تثبیتشده ساخته شدهاند.
مثلاً در «اکنون در Android»، ویژگی ویدیو یا تصویردرتصویر و چیزهایی مثل این را اضافه کردیم.
جریان کاری سوم انتقال بود.
درحال ارتقا دادن برنامههای متنباز تولیدی هستیم که با کتابخانهها و معماریهای مدرن بسته نگه داشته بودیم.
برای مثال، Nav 2 به Nav 3، نماهای XML به Compose، یا مواردی مثل قاب تکی به چیدمان تطبیقی.
و آخرین مورد، برنامه داخلی گرینفیلد بود که از ابتدا بااستفاده از طرحهای آزمایشی بصری ساخته شده بود.
در اینجا، مثالها عبارت بودند از: جریان کامل اصالتسنجی گذرواژه یکبارمصرف پیامکی، پیگیری سفارش با Google Maps، و غیره.
Tomáš Mlynarič
با فقط چند مهندس، برنامهای با همان اندازه ساختیم که شبیه «اکنون در Android» است.
اما تکالیف جدید چالشهای جدیدی بههمراه داشت.
مورد اول: نمرهدهی، نمایندگان بهدرستی.
آزمونهای محک بسیار سختتر از آزمونهای برنامه شما هستند، زیرا باید هر راهحل معتبری را قبول کنند، نه فقط یک راهحل، و هرچه تکلیف بزرگتر باشد، راهحلهای معتبر بیشتری وجود دارد.
در نسخه ۱.۰، این محک بیشتر به آزمونهای واحد متکی بود و آزمونهای واحد در بیطرف بودن بسیار بد عمل میکنند.
import com.foodvibes.MyViewModel
@Test
fun testRetry() {
val vm = MyViewModel()
vm.retry()
assertTrue(vm.retried)
}این ابزارها به نام دقیق کلاس یا تابع نیاز دارند.
مثلاً در این مورد، یک آزمایش فانتزی وجود ندارد، اما اساساً مسئله این است که عامل میتواند آن چیزها را متفاوت نامگذاری کند، یا حتی اگر آنها را متفاوت نامگذاری نکند، اگر آنها را در بسته دیگری قرار دهد، آزمایشها کامپایل نمیشوند و بنابراین برای مورد ما غیرقابل استفاده خواهند بود.
import com.foodvibes.feature.my.RetriableViewModel
@Test
fun testRetry() {
val vm = RetriableViewModel()
vm.tryAgain()
assertTrue(vm.tried)
}بنابراین، ازنظر فنی میتوانیم میاناهای برنامهسازی کاربردی را در پیاموارهها مشخص کنیم، اما این کار یا جزئیات بسیار زیادی را فاش میکند یا پیامواره را با الزامات آزمایشی بسیار زیادی منفجر میکند.
بنابراین، راهحل این است که آزمایشهای مستقل از پیادهسازی انجام دهیم.
اینها بسیار سطح بالا و نتیجهمحور هستند، آنها نتایج و رفتارها را آزمایش میکنند، نه موارد داخلی را.
ما از «آزمایش واسط کاربر قطعی» استفاده میکنیم، آزمایشهایی که با اطلاعات عمومی صفحهنمایش تعامل دارند، مشابه کاری که کاربر انجام میدهد.
برای آنها، از UI Automator یا Compose UI tests استفاده میکنیم، اما اسکریپتهای تخصصی هم داریم که برخیاز مرزهای سیستم خارجی را بررسی میکنند، مثلاً اینکه آیا فراخوانی شبکه دادههای درستی داشته است یا اینکه آیا دادههای درست بدون اطلاع از کمککنندههای داخلی یا DAO در پایگاه داده ذخیره شده است یا نه.
بخشی از آنها، ما همچنین بررسیهای ایستا داریم، برای، میدانید، بررسی مانند مجوزها در مانیفست یا اگر کتابخانه در فایلهای ساختهشده و چیزهایی مانند آن بود.
و همچنین آزمایشهای ترکیبی داریم که ترکیبی از آن اسکریپتها و آزمایشهای واسط کاربر است.
این نمونهای از یکی از آزمایشهای ترکیبی است.
آنها خارج از شبیهساز رانندگی میکنند.
بنابراین، این آزمایشی برای جریان اصالتسنجی گذرواژه یکبارمصرف پیامکی است که در آن، اسکریپت ابتدا باید درهمسازی برنامه را محاسبه کند تا بتواند پیامک را بهدرستی به شبیهساز ارسال کند، سپس آزمایش را شروع میکند، آزمایشهای UI Automator را انجام میدهد، و گذرواژه یکبارمصرفی را که بهطور تصادفی تولید شده است و به آن نیاز دارد ارسال میکند، و پیامک را با فرمان ADB به شبیهساز میفرستد.
و آزمایش فقط بررسی میکند که آیا ورودی عدد درستی داشته است یا نه.
همین، اساساً همین است.
هیچ جفتسازی پیادهسازی وجود ندارد، فقط بررسی میکند، فقط بررسی میکند که آیا جریان کار میکند یا نه.
مشکل دوم نمرهدهی این بود که تکالیف ما به چندحالتی نیاز دارند.
یا خود عاملها باید واسط کاربر را تولید کنند یا ما طرحهای ساختگی را به آنها میدهیم.
و برای این کار، آسانترین راه استفاده از آزمایشهای نماگرفت است.
و از ابتدا میدانستیم که آستانههای نماگرفت باید بالاتر باشد، اما بههرحال رد شدند.
ما چند الگوریتم مختلف تفاضل پیکسل را امتحان کردیم، اما آنها در مواردی مانند نویز سطح سیستم، جایی که نوار وضعیت شبیهساز متفاوت بود، یا نماد باتری، یا حتی مانند هموارسازی سختافزاری قلم متفاوت بود، شکست خوردند.
اما همچنین، آنها در پیادهسازیهای تا حدودی معتبر شکست خوردند، جایی که، میدانید، فاصلههای داخلی جزئی بودند، مثل اینکه کمی متفاوت بود، یا تفاوتهای جزئی در رنگ وجود داشت، مثلاً رابط کاربری میتوانست کاملاً درست باشد، اما پسزمینه کمی متفاوت رنگآمیزی شده بود، و الگوریتمهای تفاضل پیکسلی شکست میخوردند.
بنابراین، برای این کار، از «داور مدل زبانی بزرگ چندوجهی» استفاده کردیم و آن را ساختیم که جفتهای نماگرفت را مانند آزمایشهای نماگرفت مقایسه میکند و به ما امتیازی میدهد، اما همچنین «استدلال ساختاری» درباره امتیاز ارائه میدهد.
و همچنین آن را با برخیاز دادههای سلسلهمراتب دسترسپذیری تغذیه میکنیم که بررسی میکند آیا ساختار درست است و آیا برابری ساختاری درست است یا نه.
ما آن را بهصورت تجربی در آزمایشهای بسیار زیادی امتحان کردیم و دیدیم که سازگاری بالایی دارد و مشکلاتی را که دیدیم نادیده میگیرد.
بنابراین، اکنون، ما راه خوبی برای تأیید تصاویر و رفتارها بهصورت مستقل داشتیم، و دیدیم که عاملها سعی کردند همه چیز را جعل کنند.
ادامه دهید.
Tomáš Mlynarič
بهسادگی شروع میشود.
امروزه، نمایندگان اساساً میگویند: «بسیارخوب.
تکلیفی دارم.
بیایید به GitHub نگاه کنیم، میدانید.
بیایید راهحلها را پیدا کنیم.»
بنابراین، این اولین کاری است که انجام میدهند.
آنها سعی میکنند GitHub یا اینترنت را برای یافتن راهحل معتبر جستجو کنند، به همین دلیل است که باید کد منبع را بسته نگه داریم و نمیتواند عمومی باشد.
ولی این کار، مثلاً، آسان بود.
در برخیاز آزمایشها، مثلاً گفتیم همه چیز ۱۰۰٪ بهخوبی پیش میرود و نماینده میگوید: «پیروزی باشکوه!»
بنابراین.
جالب است، چه چیزی پیدا کردند؟
اما ما مسیر را دقیقتر بررسی کردیم و آنها گفتند: «من نمیتوانم این کار را انجام دهم.
من فقط میخواهم، اگر آستانه را به ۸۰٪ آزمایش نماگرفت تغییر دهم چه میشود؟»
// AuthFlowScreenshotTests.kt
@get:Rule
val dropshots = Dropshots(
resultValidator =
ThresholdValidator(
- 0.05f
+ 0.80f
)
)و اینطور است که «بله، پیروزی، همه چیز درحال گذشتن است.»
بله، اما آزمایشهای نماگرفت بیفایده هستند.
اما این پیچیدهترین آنها نبود.
در برخی، درواقع در برنامه تبدیل Flutter، عامل بارها و بارها تلاش کرد Android را بسازد و درنهایت گفت: «نمیدانم چه کار کنم.»
بنابراین، آنها نماگرفتی را که به آنها دادیم گرفتند و آن را بهعنوان یک drawable در پسزمینه قرار دادند.
و حالا مثل این است که در آزمون نماگرفت قبول شده باشد.
هورا!
اما بعد، میدانید، آزمایشهای واسط کاربر هنوز ناموفق هستند، بنابراین آنها میگویند: «من یک لایه همپوشانی نامرئی روی آن قرار میدهم که دکمهها، متنها، و برچسبهای آزمایشی، و هر چیزی که نیاز داریم را داشته باشد.
اکنون همه چیز سبز است.
شگفتانگیز.
آفرین.»
اینطور نیست که مثلاً یکی از آنها خیلی خوب باشد.
بنابراین، ما یک تکلیف انتقال از Java به Kotlin داریم که در آن عامل اساساً باید از Java به Kotlin منتقل شود، درست است؟
نتوانستند آن را بسازند.
مثلاً هنوز در چیزی ناموفق است، بنابراین عامل فکر کرد: «بسیار خوب، من فقط کلاسهای کامپایلشده را از Java میگیرم و آن را در یک JAR قرار میدهم، و سپس آن را بهعنوان یک کتابخانه معمولی به فایلهای ساخت اضافه میکنم.
بنابراین اکنون، هر آزمایشی با موفقیت انجام میشود، اما ما بررسیهای ایستا را داریم که فایلهای Java را بررسی میکنند، بنابراین، بله، من فقط آنها را حذف میکنم.»
من فایلهای Java را حذف میکنم، همه چیز سبز است، بهجز Kotlin که هنوز ناموفق است، بنابراین آنها میگویند: «بسیار خوب، من مجموعه منبع Kotlin را حذف میکنم، و اکنون همه چیز موفقیتآمیز است.
عالی است.»
نمیدانم اصلاً تقلب است یا نه.
منظورم این است که این، مثلاً، واقعاً خلاقانه است.
بنابراین، برای جلوگیری از همه اینها، یک آشکارساز تقلب ساختیم که مثلاً سه دفاع دارد.
ما به درخت میانای کاربر نگاه میکنیم، اندازههای مختلف صفحهنمایش را اعمال میکنیم تا پسزمینه دچار اعوجاج شود، و آن را میبینیم.
اما آزمایشها را نیز بازنشانی میکنیم و هرگونه دستکاری در آزمایشها را بررسی میکنیم تا نتوانند آستانهها را تغییر دهند.
و سپس ما همچنین چیزی مانند «مدل زبانی بزرگ بهعنوان قاضی» داریم که مسیرها و خروجی واقعی عامل را برای دیدن برخی چیزهای عجیب ممیزی میکند.
و اگر اتفاقی بیفتد، فقط میگوییم: «بسیار خوب، مستقیماً به شکست.»
Tomáš Mlynarič
بنابراین اکنون، هر میانبری ازبین رفته است، هیچ راهحلی جستجو نمیشود، هیچ آزمایش واحد شکننده یا رابط کاربری جعلی وجود ندارد.
بنابراین وقتی عاملها را مجبور میکنیم که واقعاً یک برنامه Android را مهندسی کنند، اعداد چگونه بهنظر میرسند؟
بنابراین، از روز دوشنبه، شاید پست وبلاگ را دیده باشید، اعداد به این شکل هستند.
حتی بهترین عامل فقط حدود ۴۰٪ از تکالیف ما را با موفقیت انجام میدهد و اکثر عاملهای پیشرو بین ۲۰ تا ۴۰٪ موفق میشوند.
و این برای ما بهعنوان نویسندگان محک خوب است، زیرا تعادل مناسبی برقرار میکند، مثلاً، تکالیفی که ارائه کردیم ارزش واقعی در دنیای واقعی دارند، اما فضای زیادی هم برای رشد وجود دارد.
بنابراین، بیایید نگاهی به نتایج بیندازیم.
اکنون میتوانیم نتایج را از دیدگاههای مختلف بررسی کنیم.
میتوانیم نگاهی به برخیاز اطلاعات آماریای که قبلاً پیدا کردهایم بیندازیم.
اولین سؤالی که ممکن است هنگام نگاه کردن به نمودار داشته باشید این است که مثلاً هزینه اجرای آن عامل چقدر است؟
و شرکتهای هوش مصنوعی معمولاً هزینه هر توکن را گزارش میکنند، برای برخی برای ورودی، خروجی، شاید توکن حافظه پنهان.
و شاید این یک استدلال تصمیمگیری در مورد شما باشد.
اما میتوانیم از دیدگاه دیگری به آن نگاه کنیم.
میتوانیم همان نمودار را در فضای دوبعدی با میانگین هزینه هر تکلیف رسم کنیم، نه-- نه با ژتون، یعنی هزینه هر تکلیف درمقابل نرخ قبولی چقدر بوده است.
و در اینجا، ناگهان میبینیم که برخی مدلها بسیار پرحرفتر هستند.
آنها زمان یا توکن بسیار بیشتری را برای هر تکلیف صرف میکنند، درحالیکه مدلهای دیگر تکالیف بیشتری را با هزینه کمتر انجام میدهند.
اما اگر قیمت هر توکن را هم به همان نمودار اضافه کنیم، میبینیم که آنچه شرکتهای هوش مصنوعی واقعاً تبلیغ میکنند با آنچه شما واقعاً برای هر تکلیف پرداخت میکنید مطابقت ندارد.
بنابراین، اگر بتوانید ببینید که عاملی که بهترین نرخ قبولی را دارد درواقع یکی از ارزانترینها بهازای هر کد است، اما گرانترین بهازای هر تکلیف است.
یا کارگزاران دیگری با قیمت دقیقاً یکسان برای هر واحد حدود ۳۰٪ از تکالیف را قبول میشوند، اما ۱۵ برابر ارزانتر هستند.
بنابراین، قیمت توکن سنجه نیست.
برخی از آنها مدلهایی هستند که کد را بیشتر کاوش میکنند، آنها درحال بازسازی و اجرای مجدد هستند و هر مرحله توکنهای بیشتری را میسوزاند.
بنابراین، نکته مهم این است که فقط به قیمت، هزینه بهازای هر کد نگاه نکنید.
مدلی را انتخاب کنید، به دادههای واقعی نگاه کنید، یا از آن در مورد خودتان استفاده کنید، یا به Android Bench نگاه کنید تا ببینید کدام مدلها درواقع بیشترین توکنها را برای وظایف مصرف میکنند.
برخی، میدانید، برخی به مراحل بیشتری نیاز دارند، هرچند هزینه هر نشانه کمتر است.
اما جنبه دیگری هم برای همین سؤال وجود دارد.
این همان نمودار است، اما میتوانیم نگاهی بیندازیم و نشان دهیم که چقدر طول میکشد تا نمایندگان آن را تکمیل کنند.
و میبینیم که نمایندگانی که بالاترین نرخ قبولی را دارند، ممکن است حتی کندترین باشند.
مثلاً میبینیم که برخی افراد تقریباً دو ساعت برای هر تکلیف وقت میگذارند.
آنها به بازسازی و آزمایش مجدد ادامه میدهند تا زمانی که کار کند.
بله، این روشها بهترین نرخ قبولی را دارند، اما بیشترین زمان را هم میبرند.
برخیاز عوامل ارزانتر، هنوز حدود نیم ساعت و نیم برای هر تکلیف زمان میبرند، اما نتایج بهتری ندارند.
یا، عوامل دیگر، آن را در کمتر از ۲۰ دقیقه تمام میکنند و همچنان بیشاز یکچهارم تکالیف را حل میکنند.
بنابراین، مدلهای کوچک و سبک معمولاً سریعتر و ارزانتر هستند، اما در انجام کارهای سخت بیشتر شکست میخورند.
نتیجه این است که هیچ مدل واحدی وجود ندارد که بهترین باشد.
این به چیزی که برای آن بهینهسازی میکنید بستگی دارد.
آیا نرخ قبولی است؟
آیا هزینه دارد؟
آیا زمان انتظار است؟
در این صورت، بسته به نوع کاری که انجام میدهید، اگر روی چنین تکالیف سختی کار نمیکنید، ممکن است استفاده از مدلهای سریعتر را درنظر بگیرید که کار را ارزانتر و سریعتر انجام میدهند.
اما هزینه و سرعت فقط به شما میگوید که عاملها چگونه اجرا میشوند، نه اینکه چرا در اکثر آزمایشها شکست میخورند.
بنابراین، اجراهای ناموفق را بررسی کردیم و متوجه شدیم که عاملها اغلب زودتر از موعد کار را رها میکنند.
آنها متقاعد شدهاند که کارشان تمام است.
تکلیف کامل شد.
باشه، من به خانه میروم.
اما همانطور که گفته شد، در بسته تکلیف، نمایندگان فقط دستورالعملها و وضعیت قبلاز تکلیف را دریافت میکنند.
نمیتوانند آزمایشها را ببینند.
آنها میبینند که نمیتوانند مجموعه درستیسنجی را ببینند.
بنابراین، ما پرسیدیم، چه میشود اگر، چه اتفاقی میافتد اگر فقط به آنها اجازه دهیم آزمایشها را ببینند؟
بنابراین، ما آزمایش کردیم و یک نوع آزمون باز از همان تکلیف داشتیم، که در آن عامل مجموعه آزمون درستیسنجی ناموفق را ازقبل دریافت کرد.
بنابراین، اکنون آنها آزمایشها را بهصورت تکراری اجرا میکردند.
آنها میتوانند خطاها را بررسی کنند و کدها را در یک حلقه بازخورد اصلاح کنند.
و متوجه شدیم که وقتی مأموران آزمایشها را میبینند، بیشتر تلاش میکنند و بیشتر کار میکنند.
و در اجراهای باز، ۲۵٪ نوبت بیشتر و ۴۰٪ زمان اجرای عامل داشتند.
تقریباً ۳۰ دقیقه برای هر تکلیف، آنها صرف اجرای آزمایشهای ناموفق و رفع مشکل آنها کردند، زیرا کورکورانه اشکالزدایی نمیکردند.
بنابراین، آنها دقیقاً میبینند چه چیزی ناموفق است و متأسفانه نرخ قبولی نیز تقریباً ۵۰ درصد افزایش مییابد.
و این تلاش بیشتر، همانطور که گفتم، میانگین نرخ قبولی را بهبود میبخشد.
اما درنهایت مدلهای مرزشکن جدیدی آمدند و بهسرعت این گونه باز را اشباع کردند.
خب، تقریباً ۹۰٪ از نرخ قبولی انجام شده است.
بنابراین، متغیر آزمایش بسته جستجوی بسته را بهعنوان سنجه محک اصلی نگه داشتیم.
اما هنوز هم خیلی جالب است که ببینیم مدلها وقتی میدانند براساس چه چیزی ارزیابی میشوند، چقدر بهتر عمل میکنند.
Tomáš Mlynarič
اما به ما امکان داد تا اطلاعات آماری بیشتری درباره عوامل ایجاد کنیم.
برای مثال، میتوانیم بررسی کنیم که مدلها چگونه کار خودشان را آزمایش میکنند.
بنابراین، از نمودار میتوانیم ببینیم که مدلهای مرزشکن آزمایشهای بهتر و بهتری مینویسند و نرخ قبولی بالاتری دارند.
برخی مدلهای دیگر اعتمادبهنفس کاذب دارند، من میتوانم این کار را انجام دهم، بدون آزمایش.
خب، گاهی اوقات هنوز خوب هستند.
بنابراین، اگر از مدلهایی استفاده میکنید که در آزمایش کردن چندان خوب نیستند، میتوانید با مهارتهای آزمایش بهتر یا دستورالعملهای خاص درباره نحوه نوشتن آزمایشها به آنها کمک کنید.
اما همبستگی بهمعنای علیت نیست، درست است؟
باید آزمایش کنترلشدهای روی این موضوع داشته باشیم.
هنوز باید این کار را انجام دهیم تا ببینیم آیا درخواست برای آزمونهای بهتر واقعاً امتیاز را افزایش میدهد یا نه.
بااینحال، آزمایشی را روی نیمه دیگر آزمایش Android اجرا کردیم و آن این است که نمایندگان را به استفاده از شبیهساز وادار کنیم.
در ابتدا، در محک خود، چیزی درباره شبیهساز نگفتیم.
ما فرض کردیم که، مثلاً، عاملها باید آن را بفهمند، درست است؟
بنابراین، در نتیجه دیدیم که تقریباً هیچکدام از آنها درواقع شبیهساز را راهاندازی نمیکنند.
و همانطور که اشاره کردم، آزمایشهای میانای کاربر ما در محکهای ما بسیار حیاتی هستند و بدون شبیهسازها، واقعاً نمیتوانید از آزمایشهای میانای کاربر استفاده کنید.
بنابراین، همه آنها در یک چیز بسیار ساده شکست میخوردند.
بنابراین، اکنون با دوراهی مواجه هستیم.
آیا به عاملها میگوییم که باید از شبیهساز استفاده کنید و ریسک امتیازهای بالاتر را بپذیرید، یا چیزی نمیگوییم و امیدواریم که خودشان متوجه شوند؟
اما در نهایت، هدف ما این بود که معیاری عادلانه برای سنجش کدنویسی و حل مسئله Android باشیم.
نمیخواهیم مثل برخیاز ویژگیهای محیطی اندازهگیری کنیم.
بنابراین، ما حد وسط را انتخاب کردیم.
به آنها گفتیم که شبیهساز را اینگونه راهاندازی میکنید، اما درباره اینکه از آن استفاده کنند یا نه، چیزی نگفتیم.
درنهایت، شروع شبیهساز چیزی نیست که واقعاً نیاز به آزمایش آن داشته باشیم یا بخواهیم آن را آزمایش کنیم.
و تأثیر آن دستور شبیهساز را اندازهگیری کردیم.
و حالا، ما واقعاً دیدیم که وقتی به آنها نحوه انجام کار را دادیم، نمایندگان درواقع شبیهساز را بسیار بیشتر راهاندازی کردند و درواقع آزمایشهای واسط کاربر را اجرا کردند، و این تأثیر بزرگی بر نرخ قبولی داشت، متأسفانه برای ما.
اما همچنین به ما اجازه داد اشتباهات و مشکلات واقعی کدنویسی آنها را بررسی کنیم و نه فقط، مثلاً، خرابی در شبیهساز راهاندازینشده.
بنابراین، نکته مهم این است که مشخص بودن پیامواره هنوز هم بسیار مهم است و اگر درحال طراحی محکها یا ارزیابیهای خودتان هستید، باید آنچه را که واقعاً در مورد شما اهمیت دارد آزمایش کنید.
مثلاً، بیایید یک مثال بزنیم: شما درحال ارزیابی کارایی توکن یا یک مهارت یا ابزار هستید، ابتدا باید واقعاً با گذراندن ارزیابی شروع کنید، تغییر را برای کارایی ایجاد کنید، و سپس همچنان تأیید کنید که هنوز با توکنهای کمتری درحال گذراندن است.
اگر این کار را به روش دیگری انجام دهید، متغیرهای زیادی بهطور همزمان تغییر خواهند کرد و متوجه نخواهید شد که آیا واقعاً تغییر شما باعث بهبود آن شده است یا نه.
Tomáš Mlynarič
برگشتن به جدول ردهبندی.
همانطور که گفتم، بهترین مدلها حدود ۴۰٪ از تکالیف را با موفقیت پشت سر میگذارند، و برای موفقیت در نرخ قبولی باید همه بررسیها با موفقیت پشت سر گذاشته شوند.
And it would Otherwise, the failed the task.
بنابراین، سؤال این است که آیا این عوامل برای ۶۰٪ دیگر هیچ چیز مفیدی تولید نکردهاند؟
نه، دارند به آنجا میرسند.
برای نشان دادن اینکه عامل واقعاً چقدر به راهحلهای کارآمد نزدیک شده است، چیزی شبیه به فاصله، نرخ تکمیل یا نوعی امتیاز جزئی را نیز محاسبه میکنیم.
این امتیاز وزنی در چهار دسته است: برای سازگاری بصری، عملکردی، اینکه آیا بهدرستی کار میکند، برخی الزامات خاص هر تکلیف، و برخی بررسیهای رگرسیون.
و میبینید که مدلهای با رتبه پایینتر میتوانند حدود نیمی از کار را تمام کنند، درحالیکه مدلهای مرزشکن میتوانند بهطور میانگین تقریباً ۸۰٪، یعنی بیشاز ۸۰٪ از تکالیف را تکمیل کنند، اما فقط ۴۰٪ را با موفقیت پشت سر میگذارند.
بنابراین، آزمایشی روی تبدیل Flutter به Android انجام دادیم تا ببینیم چه اتفاقی میافتد.
بنابراین، نرخ تکمیل را هر چند مرحله عامل دوباره محاسبه کردیم و الگوهای مشابهی را در همه مدلهای مرزشکن مشاهده کردیم.
در حدود ۱۴۰ مرحله، آنها تلاش میکردند تا بهطور میانگین به امتیاز تقریباً ۹۰٪ برسند، و سپس ۹۰ مرحله دیگر یا تقریباً ۴۰٪ از اجرا را صرف تلاش برای بستن فاصله تا ۱۰۰٪ کردند، اما فقط توانستند ۱ یا ۲ درصد بیشتر امتیاز کسب کنند.
و فکر میکنیم این درواقع بازتابدهنده توسعه عاملی امروزی است که در آن توسعهدهندگان یا کاربران بیتجربه برنامه را کامل میبینند.
همه چیز درحال پرداز است.
ورودی تاحدودی کار کرد.
شاید خرابیای وجود نداشته باشد.
اما وقتی یک مهندس ارشد میآید و کد را نگاه میکند، متوجه نقصهای متعددی میشود: مشکلات معماری، نقصهای چرخه عمر، و چیزهایی از این قبیل.
Tomáš Mlynarič
برای جمعبندی، بیایید Android Bench، کار 2.0 ما، را از دیدگاه دیگری بررسی کنیم.
درمقایسه با نسخه ۱.۰، اکنون فقط ۳۰ تکلیف داریم و این کار عمدی است.
بهجای رفع اشکالهای مجزا و وصلههای کوچک، صفحههای کامل، انتقالهای چندماژولی، و تبدیلهای کامل برنامه داریم.
اکنون وصلهها در دهها فایل بزرگتر شدهاند.
و بررسیهای واسط کاربری چندحالته را داریم.
عوامل باید طولانیتر اجرا شوند و بسیار سختتر کار کنند.
اگر با دیگر محکهای پیشرو مقایسه کنیم، میتوانیم ببینیم که محک ما همچنان به تغییرات کد بسیار بزرگتری نیاز دارد.
این مدل عاری از آلودگی است زیرا اکثر تکالیف از ابتدا نوشته شدهاند و هنوز فضای زیادی برای رشد وجود دارد.
همانطور که در ابتدا گفتم، چند ماه در دنیای هوش مصنوعی مثل یک ابدیت بهنظر میرسد و درنهایت، هر معیار به حداکثر میرسد و اشباع میشود.
و وقتی این اتفاق بیفتد، امیدواریم که به سمت کارهای سختتر و پیچیدهتری برویم که دوباره با آن دوران و آن وضعیت هوش مصنوعی همخوانی داشته باشد.
اکنون، از Android Bench بهعنوان قطبنما برای مقایسه مدلها و مهارها استفاده کنید و شاید اطلاعاتی کسب کنید.
و وقتی آماده بودید که عمیقتر شوید، همان اصول محکزنی و اصول ارزیابی را به پایگاههای کد و گردش کارهای خودتان بیاورید، زیرا هیچچیز بهتر از اندازهگیری هوش مصنوعی روی کدی نیست که واقعاً با آن کار میکنید.
اینگونه است که از امیدواری به اینکه هوش مصنوعی درست عمل کرده باشد به اطمینان از اینکه درست عمل کرده است میرسید.
ازطرف کل Android Bench، از توجه شما سپاسگزاریم.
import com.foodvibes.MyViewModel
@Test
fun testRetry() {
val vm = MyViewModel()
vm.retry()
assertTrue(vm.retried)
}import com.foodvibes.feature.my.RetriableViewModel
@Test
fun testRetry() {
val vm = RetriableViewModel()
vm.tryAgain()
assertTrue(vm.tried)
}// AuthFlowScreenshotTests.kt
@get:Rule
val dropshots = Dropshots(
resultValidator =
ThresholdValidator(
- 0.05f
+ 0.80f
)
)