import React, { useState } from "react"; import { Box, Paper, Typography, TextField, Button, FormControl, InputLabel, Select, MenuItem, FormControlLabel, Switch, Stack, Grid, CircularProgress, Alert, } from "@mui/material"; import RocketLaunchIcon from "@mui/icons-material/RocketLaunch"; import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline"; import ThumbUpIcon from "@mui/icons-material/ThumbUp"; import { alpha } from "@mui/material/styles"; import InfoIconWithTooltip from "../../../../components/shared/InfoIconWithTooltip"; import { MODEL_TYPES } from "../../../../pages/LeaderboardPage/components/Leaderboard/constants/modelTypes"; import { SUBMISSION_PRECISIONS } from "../../../../pages/LeaderboardPage/components/Leaderboard/constants/defaults"; import AuthContainer from "../../../../components/shared/AuthContainer"; const WEIGHT_TYPES = [ { value: "Original", label: "Original" }, { value: "Delta", label: "Delta" }, { value: "Adapter", label: "Adapter" }, ]; const HELP_TEXTS = { modelName: ( Model Name on Hugging Face Hub Your model must be public and loadable with AutoClasses without trust_remote_code. The model should be in Safetensors format for better safety and loading performance. Example: mistralai/Mistral-7B-v0.1 ), revision: ( Model Revision Git branch, tag or commit hash. The evaluation will be strictly tied to this specific commit to ensure consistency. Make sure this version is stable and contains all necessary files. ), modelType: ( Model Category 🟢 Pretrained: Base models trained on text using masked modeling 🟩 Continuously Pretrained: Extended training on additional corpus 🔶 Fine-tuned: Domain-specific optimization 💬 Chat: Models using RLHF, DPO, or IFT for conversation 🤝 Merge: Combined weights without additional training 🌸 Multimodal: Handles multiple input types ), baseModel: ( Base Model Reference Required for delta weights or adapters. This information is used to identify the original model and calculate the total parameter count by combining base model and adapter/delta parameters. ), precision: ( Model Precision Size limits vary by precision: • FP16/BF16: up to 100B parameters • 8-bit: up to 280B parameters (2x) • 4-bit: up to 560B parameters (4x) Choose carefully as incorrect precision can cause evaluation errors. ), weightsType: ( Weights Format Original: Complete model weights in safetensors format Delta: Weight differences from base model (requires base model for size calculation) Adapter: Lightweight fine-tuning layers (requires base model for size calculation) ), chatTemplate: ( Chat Template Support Activates automatically for chat models. It uses the standardized Hugging Face chat template for consistent prompt formatting during evaluation. Required for models using RLHF, DPO, or instruction fine-tuning. ), }; // Convert MODEL_TYPES to format expected by Select component const modelTypeOptions = Object.entries(MODEL_TYPES).map( ([value, { icon, label }]) => ({ value, label: `${icon} ${label}`, }) ); function ModelSubmissionForm({ user, isAuthenticated }) { const [formData, setFormData] = useState({ modelName: "", revision: "main", modelType: "fine-tuned", isChatModel: false, useChatTemplate: false, precision: "float16", weightsType: "Original", baseModel: "", }); const [error, setError] = useState(null); const [submitting, setSubmitting] = useState(false); const [success, setSuccess] = useState(false); const [submittedData, setSubmittedData] = useState(null); const handleChange = (event) => { const { name, value, checked } = event.target; setFormData((prev) => ({ ...prev, [name]: event.target.type === "checkbox" ? checked : value, })); }; const handleSubmit = async (e) => { e.preventDefault(); setError(null); setSubmitting(true); try { const response = await fetch("/api/models/submit", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ model_id: formData.modelName, revision: formData.revision, model_type: formData.modelType, precision: formData.precision, weight_type: formData.weightsType, base_model: formData.baseModel, use_chat_template: formData.useChatTemplate, user_id: user.username, }), }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || "Failed to submit model"); } setSubmittedData(formData); setSuccess(true); } catch (error) { setError(error.message); } finally { setSubmitting(false); } }; if (success && submittedData) { return ( ({ p: 6, mb: 3, bgcolor: alpha(theme.palette.success.main, 0.05), borderColor: alpha(theme.palette.success.main, 0.2), })} > Model submitted successfully! Your model {submittedData.modelName} has been added to the evaluation queue with the following parameters: Model: {submittedData.modelName} Type: {submittedData.modelType} Revision: {submittedData.revision} Precision: {submittedData.precision} Weight type: {submittedData.weightsType} {submittedData.baseModel && ( Base model: {submittedData.baseModel} )} Chat template: {submittedData.useChatTemplate ? "Yes" : "No"} An automatic upvote has been added to your model to help with prioritization. ); } return ( <> {error && ( {error} )} {isAuthenticated && ( {/* Header */} theme.palette.mode === "dark" ? alpha(theme.palette.divider, 0.1) : "grey.200", bgcolor: (theme) => theme.palette.mode === "dark" ? alpha(theme.palette.background.paper, 0.5) : "grey.50", }} > Model Submission Form {/* Form Content */} {/* Model Information */} Model Information ), }} /> ), }} /> {/* Model Configuration */} Model Configuration Model Type } label="Use Chat Template" /> Precision Weights Type {formData.weightsType !== "Original" && ( ), }} /> )} {/* Submit Button */} All fields marked with * are required )} ); } export default ModelSubmissionForm;