Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
| <html lang="en"> | |
| <body class="bg-white dark:bg-slate-900"> | |
| <style> | |
| html[dir="rtl"] #submitPage { | |
| direction: rtl; | |
| text-align: right; | |
| } | |
| html[dir="rtl"] #submitPage .submit-title-icon { | |
| margin-left: 0.75rem; | |
| margin-right: 0; | |
| } | |
| html[dir="rtl"] #submitPage .submit-select-icon { | |
| left: 0.75rem; | |
| right: auto; | |
| } | |
| html[dir="rtl"] #submitPage #submitBtn { | |
| flex-direction: row-reverse; | |
| } | |
| html[dir="rtl"] #submitPage #sidebar-status-container button, | |
| html[dir="rtl"] #submitPage #sidebar-status-container .text-xs, | |
| html[dir="rtl"] #submitPage #submitAboutBody { | |
| text-align: right; | |
| } | |
| </style> | |
| <div id="submitPage" class="grid grid-cols-1 lg:grid-cols-2 gap-8"> | |
| <div class="lg:col-span-1 space-y-4"> | |
| <div | |
| class="bg-white dark:bg-slate-800 p-8 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700"> | |
| <h3 class="text-xl font-bold mb-6 flex items-center text-slate-800 dark:text-slate-100"> | |
| <span | |
| class="submit-title-icon bg-indigo-100 dark:bg-indigo-900 text-indigo-600 dark:text-indigo-300 p-2 rounded-full mr-3"> | |
| <i data-lucide="rocket" class="w-5 h-5"></i> | |
| </span> | |
| <span id="submitTitle">Submit Model</span> | |
| </h3> | |
| <form id="submitForm" class="space-y-6"> | |
| <div class="grid grid-cols-1 gap-6"> | |
| <div class="space-y-4"> | |
| <div><label id="submitLabelModelName" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Model Name</label><input required name="model_name" type="text" | |
| placeholder="myorg/mymodel" | |
| class="w-full px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 dark:text-white focus:ring-2 focus:ring-indigo-500 outline-none transition"> | |
| </div> | |
| <div><label id="submitLabelModelType" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Model Type</label> | |
| <div class="relative"><select name="model_type" | |
| class="w-full px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 dark:text-white focus:ring-2 focus:ring-indigo-500 outline-none appearance-none transition cursor-pointer"> | |
| <option id="submitOptionBase" value="base">🟢 Base</option> | |
| <option id="submitOptionInstruct" value="instruct" selected>🔶 Instruct</option> | |
| </select><i data-lucide="chevron-down" class="submit-select-icon absolute right-3 top-3 h-4 w-4 text-slate-400 pointer-events-none"></i> | |
| </div> | |
| </div> | |
| <!-- <div><label | |
| class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Precision</label> | |
| <div class="relative"><select name="precision" | |
| class="w-full px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 dark:text-white focus:ring-2 focus:ring-indigo-500 outline-none appearance-none transition cursor-pointer"> | |
| <option value="float16">float16</option> | |
| <option value="bfloat16" selected>bfloat16</option> | |
| <option value="8bit">8bit</option> | |
| <option value="4bit">4bit</option> | |
| </select><i data-lucide="chevron-down" | |
| class="absolute right-3 top-3 h-4 w-4 text-slate-400 pointer-events-none"></i> | |
| </div> | |
| </div> --> | |
| </div> | |
| <!-- <div class="space-y-4"> | |
| <div><label | |
| class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Revision | |
| Commit</label><input name="revision" type="text" value="main" placeholder="main" | |
| class="w-full px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 dark:text-white focus:ring-2 focus:ring-indigo-500 outline-none transition font-mono text-sm"> | |
| </div> | |
| <div><label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Weight | |
| Type</label> | |
| <div class="relative"><select name="weight_type" | |
| class="w-full px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 dark:text-white focus:ring-2 focus:ring-indigo-500 outline-none appearance-none transition cursor-pointer"> | |
| <option value="Original" selected>Original</option> | |
| <option value="Adapter">Adapter</option> | |
| <option value="Delta">Delta</option> | |
| </select><i data-lucide="chevron-down" | |
| class="absolute right-3 top-3 h-4 w-4 text-slate-400 pointer-events-none"></i> | |
| </div> | |
| </div> | |
| <div><label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Base | |
| Model <span class="text-xs text-slate-400 font-normal">(if | |
| adapter)</span></label><input name="base_model" type="text" | |
| placeholder="e.g. myorg/base-model" | |
| class="w-full px-4 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 dark:text-white focus:ring-2 focus:ring-indigo-500 outline-none transition"> | |
| </div> | |
| </div> --> | |
| </div> | |
| <div class="pt-4 border-t border-slate-100 dark:border-slate-700"> | |
| <button type="submit" id="submitBtn" | |
| class="w-full py-3 px-4 rounded-xl shadow-lg shadow-indigo-500/30 text-sm font-bold text-white bg-indigo-600 hover:bg-indigo-700 transition-all flex justify-center items-center gap-2 group"><span id="submitBtnLabel">Submit Model</span><i data-lucide="arrow-right" | |
| class="w-4 h-4 group-hover:translate-x-1 transition-transform"></i></button> | |
| </div> | |
| <div id="submitMsg" class="text-center text-sm font-medium min-h-[20px]"></div> | |
| </form> | |
| </div> | |
| </div> | |
| <div class="lg:col-span-1 space-y-4"> | |
| <h3 id="submitStatusTitle" class="text-lg font-bold text-slate-800 dark:text-slate-100 mb-4 px-2">Evaluation Status</h3> | |
| <div id="sidebar-status-container" class="space-y-3"> | |
| <div id="submitQueueLoading" class="p-4 text-center text-sm text-slate-400 animate-pulse">Loading queue...</div> | |
| </div> | |
| <div | |
| class="mt-6 p-4 bg-slate-50 dark:bg-slate-800/50 rounded-xl border border-slate-200 dark:border-slate-700 text-xs text-slate-500 dark:text-slate-400 leading-relaxed"> | |
| <h4 id="submitAboutTitle" class="font-bold text-slate-700 dark:text-slate-300 mb-2">About Submission</h4> | |
| <p id="submitAboutBody">Submitted models are added to the queue automatically. Results appear on the leaderboard once finished.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| (function () { | |
| const SUBMIT_TRANSLATIONS = { | |
| ar: { | |
| title: "إرسال نموذج", | |
| model_name: "اسم النموذج", | |
| model_type: "نوع النموذج", | |
| base: "🟢 أساسي", | |
| instruct: "🔶 موجّه", | |
| submit_btn: "إرسال النموذج", | |
| status_title: "حالة التقييم", | |
| loading_queue: "جارٍ تحميل قائمة الانتظار...", | |
| about_title: "عن الإرسال", | |
| about_body: "تُضاف النماذج المرسلة تلقائيًا إلى قائمة الانتظار، وتظهر نتائجها على لوحة الصدارة بمجرد الانتهاء.", | |
| status_offline: "خدمة الحالة غير متاحة الآن", | |
| submitting: "جارٍ الإرسال...", | |
| success_default: "تم الإرسال بنجاح", | |
| pending: "قيد الانتظار", | |
| running: "قيد التنفيذ", | |
| finished: "مكتمل", | |
| failed: "فشل", | |
| no_status: "لا توجد تقييمات في حالة {status}.", | |
| anon: "مجهول", | |
| error_default: "حدث خطأ", | |
| }, | |
| en: { | |
| title: "Submit Model", | |
| model_name: "Model Name", | |
| model_type: "Model Type", | |
| base: "🟢 Base", | |
| instruct: "🔶 Instruct", | |
| submit_btn: "Submit Model", | |
| status_title: "Evaluation Status", | |
| loading_queue: "Loading queue...", | |
| about_title: "About Submission", | |
| about_body: "Submitted models are added to the queue automatically. Results appear on the leaderboard once finished.", | |
| status_offline: "Status offline", | |
| submitting: "Submitting...", | |
| success_default: "Submitted successfully", | |
| pending: "Pending", | |
| running: "Running", | |
| finished: "Finished", | |
| failed: "Failed", | |
| no_status: "No {status} evaluations.", | |
| anon: "anon", | |
| error_default: "Error", | |
| } | |
| }; | |
| const getText = (key, vars = {}) => { | |
| const lang = window.getCurrentLanguage ? window.getCurrentLanguage() : 'en'; | |
| const dict = SUBMIT_TRANSLATIONS[lang] || SUBMIT_TRANSLATIONS.en; | |
| let value = dict[key] ?? key; | |
| Object.entries(vars).forEach(([name, replacement]) => { | |
| value = value.replace(`{${name}}`, replacement); | |
| }); | |
| return value; | |
| }; | |
| function applySubmitTranslations() { | |
| const setTxt = (id, value) => { | |
| const el = document.getElementById(id); | |
| if (el) el.innerText = value; | |
| }; | |
| setTxt('submitTitle', getText('title')); | |
| setTxt('submitLabelModelName', getText('model_name')); | |
| setTxt('submitLabelModelType', getText('model_type')); | |
| setTxt('submitOptionBase', getText('base')); | |
| setTxt('submitOptionInstruct', getText('instruct')); | |
| setTxt('submitBtnLabel', getText('submit_btn')); | |
| setTxt('submitStatusTitle', getText('status_title')); | |
| setTxt('submitQueueLoading', getText('loading_queue')); | |
| setTxt('submitAboutTitle', getText('about_title')); | |
| setTxt('submitAboutBody', getText('about_body')); | |
| } | |
| // 1. Handle Sidebar Loading | |
| async function updateSidebarQueue() { | |
| const container = document.querySelector('#sidebar-status-container'); | |
| if (!container) return; | |
| try { | |
| const res = await fetch('/api/queue'); | |
| const q = await res.json(); | |
| const safeQ = q || { "pending": [], "running": [], "finished": [], "failed": [] }; | |
| if (window.updateHeaderStats) { | |
| window.updateHeaderStats(safeQ); | |
| } | |
| const cf = { pending: ["text-amber-500 bg-amber-500", "clock"], running: ["text-blue-500 bg-blue-500", "loader-2"], finished: ["text-emerald-500 bg-emerald-500", "check-circle"], failed: ["text-rose-500 bg-rose-500", "x-circle"] }; | |
| container.innerHTML = Object.entries(safeQ).map(([k, items]) => ` | |
| <div class="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 overflow-hidden shadow-sm"> | |
| <button onclick="this.nextElementSibling.classList.toggle('hidden')" class="w-full flex items-center justify-between p-4 text-left hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors"> | |
| <div class="flex items-center gap-3"><div class="p-2 rounded-lg ${cf[k] ? cf[k][0] : 'text-slate-500 bg-slate-500'} bg-opacity-10 text-current"><i data-lucide="${cf[k] ? cf[k][1] : 'help-circle'}" class="w-4 h-4"></i></div><span class="text-sm font-bold capitalize text-slate-700 dark:text-slate-200">${getText(k)}</span></div><span class="text-xs font-bold px-2 py-1 rounded-full bg-slate-100 dark:bg-slate-700 text-slate-500 dark:text-slate-400">${items.length}</span> | |
| </button> | |
| <div class="hidden text-sm">${items.length ? `<div class="bg-slate-50 dark:bg-darkbg p-3 border-t border-slate-100 dark:border-slate-700 space-y-2">${items.map(i => `<div class="flex justify-between text-xs p-2 bg-white dark:bg-slate-800 rounded border border-slate-200 dark:border-slate-600"><span class="font-mono text-slate-600 dark:text-slate-300 truncate" title="${i.name}">${i.name}</span><span class="px-1.5 bg-slate-100 dark:bg-slate-700 text-slate-500 rounded">${i.user || getText('anon')}</span></div>`).join('')}</div>` : `<div class="p-4 text-xs text-center text-slate-400 bg-slate-50 dark:bg-darkbg border-t border-slate-100 dark:border-slate-700 italic">${getText('no_status', { status: getText(k).toLowerCase() })}</div>`}</div> | |
| </div>`).join(''); | |
| if (window.lucide) lucide.createIcons(); | |
| } catch (err) { | |
| console.error("Sidebar queue error:", err); | |
| container.innerHTML = `<div class="p-4 text-center text-rose-500 text-sm">${getText('status_offline')}</div>`; | |
| } | |
| } | |
| // 2. Handle Form Submission | |
| const form = document.querySelector('#submitForm'); | |
| if (form) { | |
| form.onsubmit = async (e) => { | |
| e.preventDefault(); | |
| const btn = document.querySelector('#submitBtn'); | |
| const msg = document.querySelector('#submitMsg'); | |
| btn.disabled = true; | |
| btn.innerHTML = `<i data-lucide="loader-2" class="w-4 h-4 animate-spin"></i> ${getText('submitting')}`; | |
| if (window.lucide) lucide.createIcons(); | |
| try { | |
| const res = await fetch('/api/submit', { method: 'POST', body: new FormData(e.target) }); | |
| const json = await res.json(); | |
| if (!res.ok) throw new Error(json.detail ? JSON.stringify(json.detail) : (json.message || "Error")); | |
| msg.className = "text-center text-sm font-medium text-emerald-600 dark:text-emerald-400"; | |
| msg.innerText = "✅ " + (json.message || getText('success_default')); | |
| e.target.reset(); | |
| // Update Local Sidebar & Header | |
| await updateSidebarQueue(); | |
| } catch (err) { | |
| msg.className = "text-center text-sm font-medium text-rose-600 dark:text-rose-400"; | |
| msg.innerText = "❌ " + (err.message || getText('error_default')); | |
| } | |
| btn.disabled = false; | |
| btn.innerHTML = `<span>${getText('submit_btn')}</span> <i data-lucide="arrow-right" class="w-4 h-4"></i>`; | |
| if (window.lucide) lucide.createIcons(); | |
| }; | |
| } | |
| applySubmitTranslations(); | |
| if (window.registerLanguageListener) { | |
| window.registerLanguageListener(() => { | |
| applySubmitTranslations(); | |
| updateSidebarQueue(); | |
| }); | |
| } | |
| // Init | |
| updateSidebarQueue(); | |
| })(); | |
| </script> | |
| </body> | |
| </html> | |