import AutoComlete from '@/components/seal-form/auto-complete'; import CheckboxField from '@/components/seal-form/checkbox-field'; import SealInputNumber from '@/components/seal-form/input-number'; import SealInput from '@/components/seal-form/seal-input'; import SealSelect from '@/components/seal-form/seal-select'; import useAppUtils from '@/hooks/use-app-utils'; import { useIntl } from '@umijs/max'; import { Form } from 'antd'; import _ from 'lodash'; import { useMemo, useRef } from 'react'; import { backendOptionsMap } from '../config/backend-parameters'; import { useFormContext } from '../config/form-context'; import { FormData } from '../config/types'; import useQueryDraftModels from '../hooks/use-query-draftModels'; const AlgorithmMap = { Eagle3: 'eagle3', MTP: 'mtp', Ngram: 'ngram' }; const SpeculativeDecode = () => { const intl = useIntl(); const { source, backendOptions, onValuesChange } = useFormContext(); const { getRuleMessage } = useAppUtils(); const form = Form.useFormInstance(); const backend = Form.useWatch('backend', form); const speculativeEnabled = Form.useWatch( ['speculative_config', 'enabled'], form ); const algorithm = Form.useWatch(['speculative_config', 'algorithm'], form); const speculativeConfigRef = useRef({}); const { draftModelList, loading, resetDraftModels, onSearch } = useQueryDraftModels({ source }); const onValuesChangeDebounced = _.debounce(() => { const allValues = form.getFieldsValue(); onValuesChange?.({}, allValues); }, 200); const handleSpeculativeEnabledChange = (e: any) => { if (e.target.checked) { form.setFieldValue('speculative_config', { enabled: true, algorithm: speculativeConfigRef.current.algorithm || AlgorithmMap.Eagle3, draft_model: speculativeConfigRef.current.draft_model || '', num_draft_tokens: speculativeConfigRef.current.num_draft_tokens || 3, ngram_min_match_length: speculativeConfigRef.current.ngram_min_match_length || 1, ngram_max_match_length: speculativeConfigRef.current.ngram_max_match_length || 10 }); } else { speculativeConfigRef.current = form.getFieldValue('speculative_config'); onValuesChangeDebounced(); } }; const handleAlgorithemChange = (value: string) => { if (value === AlgorithmMap.Eagle3) { resetDraftModels(); } }; const builtInBackend = useMemo(() => { const currentBackend = backendOptions.find( (item) => item.value === backend ); return ( currentBackend?.isBuiltIn && [backendOptionsMap.SGLang, backendOptionsMap.vllm].includes( backend as string ) ); }, [backend, backendOptions]); return ( <> name={['speculative_config', 'enabled']} valuePropName="checked" style={{ marginBottom: 8 }} extra={ !builtInBackend && ( ) } > {speculativeEnabled && ( <> name={['speculative_config', 'algorithm']} rules={[ { required: true, message: getRuleMessage( 'select', 'models.form.algorithm', false ) } ]} > {algorithm === AlgorithmMap.Eagle3 && ( name={['speculative_config', 'draft_model']} rules={[ { required: true, message: getRuleMessage( ['select', 'input'], 'models.form.draftModel' ) } ]} > )} name={['speculative_config', 'num_draft_tokens']} > {algorithm === AlgorithmMap.Ngram && ( <> name={['speculative_config', 'ngram_min_match_length']} > name={['speculative_config', 'ngram_max_match_length']} > )} )} ); }; export default SpeculativeDecode;