Helloyunho e86cd7e661
feat: add a simple way to convert Hugging Face model to GGUF (#1972)
* chore: add react developer tools to electron

* feat: add small convert modal

* feat: separate modals and add hugging face extension

* feat: fully implement hugging face converter

* fix: forgot to uncomment this...

* fix: typo

* feat: try hf-to-gguf script first and then use convert.py

HF-to-GGUF has support for some unusual models
maybe using convert.py first would be better but we can change the usage order later

* fix: pre-install directory changed

* fix: sometimes exit code is undefined

* chore: download additional files for qwen

* fix: event handling changed

* chore: add one more necessary package

* feat: download gguf-py from llama.cpp

* fix: cannot interpret wildcards on GNU tar

Co-authored-by: hiento09 <136591877+hiento09@users.noreply.github.com>

---------

Co-authored-by: hiento09 <136591877+hiento09@users.noreply.github.com>
2024-02-26 10:57:53 +07:00

74 lines
2.1 KiB
TypeScript

import { useEffect, useState } from 'react'
import { Button } from '@janhq/uikit'
import { useAtomValue } from 'jotai'
import { useConvertHuggingFaceModel } from '@/hooks/useConvertHuggingFaceModel'
import {
conversionStatusAtom,
repoDataAtom,
} from '@/helpers/atoms/HFConverter.atom'
export const HuggingFaceConvertingModal = () => {
// This component only loads when repoData is not null
const repoData = useAtomValue(repoDataAtom)!
// This component only loads when conversionStatus is not null
const conversionStatus = useAtomValue(conversionStatusAtom)!
const [status, setStatus] = useState('')
const { cancelConvertHuggingFaceModel } = useConvertHuggingFaceModel()
useEffect(() => {
switch (conversionStatus) {
case 'downloading':
setStatus('Downloading files...')
break
case 'converting':
setStatus('Converting...')
break
case 'quantizing':
setStatus('Quantizing...')
break
case 'stopping':
setStatus('Stopping...')
break
case 'generating':
setStatus('Generating metadata...')
break
}
}, [conversionStatus])
const onStopClick = () => {
cancelConvertHuggingFaceModel(repoData.id, repoData)
}
return (
<>
<div className="flex flex-col items-center justify-center gap-1">
<p className="text-2xl font-bold">Hugging Face Converter</p>
</div>
{conversionStatus === 'done' ? (
<div className="flex flex-col items-center justify-center gap-1">
<p>Done!</p>
<p>Now you can use the model on Jan as usual. Have fun!</p>
</div>
) : (
<>
<div className="flex flex-col items-center justify-center gap-1">
<p>{status}</p>
</div>
<Button
onClick={onStopClick}
className="w-full"
loading={conversionStatus === 'stopping'}
disabled={conversionStatus === 'stopping'}
themes="danger"
>
{conversionStatus === 'stopping' ? 'Stopping...' : 'Stop'}
</Button>
</>
)}
</>
)
}