mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-07 02:58:21 +00:00
fix: create the model when a GGUF is uploaded to Ollama, in File Mode and URL Mode (#31862)
This commit is contained in:
parent
8c34af3033
commit
1b2ceedd61
2 changed files with 25 additions and 84 deletions
|
|
@ -1632,12 +1632,29 @@ async def download_file_stream(
|
|||
ssl=AIOHTTP_CLIENT_SESSION_SSL,
|
||||
timeout=aiohttp.ClientTimeout(total=30),
|
||||
) as blob_resp:
|
||||
if blob_resp.ok:
|
||||
await asyncio.to_thread(os.remove, file_path)
|
||||
yield f'data: {JSONCodec.dumps({"done": done, "blob": f"sha256:{hashed}", "name": file_name})}\n\n'
|
||||
else:
|
||||
if not blob_resp.ok:
|
||||
raise RuntimeError('Ollama: Could not create blob, Please try again.')
|
||||
|
||||
await asyncio.to_thread(os.remove, file_path)
|
||||
|
||||
model, _ext = os.path.splitext(file_name)
|
||||
async with session.post(
|
||||
f'{ollama_url}/api/create',
|
||||
headers=ollama_headers,
|
||||
cookies=ollama_cookies,
|
||||
data=JSONCodec.dumps({'model': model, 'files': {file_name: f'sha256:{hashed}'}, 'stream': False}),
|
||||
ssl=AIOHTTP_CLIENT_SESSION_SSL,
|
||||
timeout=get_client_timeout(),
|
||||
) as create_resp:
|
||||
resp_text = await create_resp.text()
|
||||
if not create_resp.ok:
|
||||
raise RuntimeError(f'Failed to create model in Ollama. {resp_text}')
|
||||
|
||||
event = JSONCodec.dumps(
|
||||
{'done': done, 'blob': f'sha256:{hashed}', 'name': file_name, 'model_created': model}
|
||||
)
|
||||
yield f'data: {event}\n\n'
|
||||
|
||||
|
||||
@router.post('/models/download')
|
||||
@router.post('/models/download/{url_idx}')
|
||||
|
|
@ -1743,6 +1760,7 @@ async def upload_model(
|
|||
create_payload = {
|
||||
'model': model,
|
||||
'files': {filename: f'sha256:{file_hash}'},
|
||||
'stream': False,
|
||||
}
|
||||
log.info('Model Payload: %s', create_payload)
|
||||
|
||||
|
|
@ -1754,6 +1772,7 @@ async def upload_model(
|
|||
ssl=AIOHTTP_CLIENT_SESSION_SSL,
|
||||
timeout=get_client_timeout(),
|
||||
) as create_resp:
|
||||
resp_text = await create_resp.text()
|
||||
if create_resp.ok:
|
||||
log.info('API SUCCESS!')
|
||||
event = JSONCodec.dumps(
|
||||
|
|
@ -1761,7 +1780,6 @@ async def upload_model(
|
|||
)
|
||||
yield f'data: {event}\n\n'
|
||||
else:
|
||||
resp_text = await create_resp.text()
|
||||
raise Exception(f'Failed to create model in Ollama. {resp_text}')
|
||||
|
||||
except Exception as exc:
|
||||
|
|
|
|||
|
|
@ -54,13 +54,9 @@
|
|||
let createModelDigest = '';
|
||||
let createModelPullProgress = null;
|
||||
|
||||
let digest = '';
|
||||
let pullProgress = null;
|
||||
|
||||
let modelUploadMode = 'file';
|
||||
let modelInputFile: File[] | null = null;
|
||||
let modelFileUrl = '';
|
||||
let modelFileContent = `TEMPLATE """{{ .System }}\nUSER: {{ .Prompt }}\nASSISTANT: """\nPARAMETER num_ctx 4096\nPARAMETER stop "</s>"\nPARAMETER stop "USER:"\nPARAMETER stop "ASSISTANT:"`;
|
||||
let modelFileDigest = '';
|
||||
|
||||
let uploadProgress = null;
|
||||
|
|
@ -300,7 +296,6 @@
|
|||
|
||||
let uploaded = false;
|
||||
let fileResponse = null;
|
||||
let name = '';
|
||||
|
||||
if (modelUploadMode === 'file') {
|
||||
const file = modelInputFile ? modelInputFile[0] : null;
|
||||
|
|
@ -353,13 +348,13 @@
|
|||
|
||||
if (data.done) {
|
||||
modelFileDigest = data.blob;
|
||||
name = data.name;
|
||||
uploaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
toast.error(`${err}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -368,65 +363,7 @@
|
|||
}
|
||||
|
||||
if (uploaded) {
|
||||
const res = await createModel(
|
||||
localStorage.token,
|
||||
`${name}:latest`,
|
||||
`FROM @${modelFileDigest}\n${modelFileContent}`
|
||||
);
|
||||
|
||||
if (res && res.ok) {
|
||||
const reader = res.body
|
||||
.pipeThrough(new TextDecoderStream())
|
||||
.pipeThrough(splitStream('\n'))
|
||||
.getReader();
|
||||
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) break;
|
||||
|
||||
try {
|
||||
let lines = value.split('\n');
|
||||
|
||||
for (const line of lines) {
|
||||
if (line !== '') {
|
||||
console.log(line);
|
||||
let data = JSON.parse(line);
|
||||
console.log(data);
|
||||
|
||||
if (data.error) {
|
||||
throw data.error;
|
||||
}
|
||||
if (data.detail) {
|
||||
throw data.detail;
|
||||
}
|
||||
|
||||
if (data.status) {
|
||||
if (
|
||||
!data.digest &&
|
||||
!data.status.includes('writing') &&
|
||||
!data.status.includes('sha256')
|
||||
) {
|
||||
toast.success(data.status);
|
||||
} else {
|
||||
if (data.digest) {
|
||||
digest = data.digest;
|
||||
|
||||
if (data.completed) {
|
||||
pullProgress = Math.round((data.completed / data.total) * 1000) / 10;
|
||||
} else {
|
||||
pullProgress = 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
toast.error(`${err}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
toast.success($i18n.t('Model created successfully!'));
|
||||
}
|
||||
|
||||
modelFileUrl = '';
|
||||
|
|
@ -1077,20 +1014,6 @@
|
|||
{/if}
|
||||
</div>
|
||||
|
||||
{#if (modelUploadMode === 'file' && modelInputFile && modelInputFile.length > 0) || (modelUploadMode === 'url' && modelFileUrl !== '')}
|
||||
<div>
|
||||
<div>
|
||||
<div class=" my-2.5 text-sm font-normal">
|
||||
{$i18n.t('Modelfile Content')}
|
||||
</div>
|
||||
<textarea
|
||||
bind:value={modelFileContent}
|
||||
class="{textareaClass} resize-none"
|
||||
rows="6"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class=" mt-1 text-xs text-gray-400 dark:text-gray-500">
|
||||
{$i18n.t('To access the GGUF models available for downloading,')}
|
||||
<a
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue