jejunepixels commited on
Commit
f835889
·
verified ·
1 Parent(s): 4b1d79b

Create upload_ui.py

Browse files
Files changed (1) hide show
  1. upload_ui.py +62 -0
upload_ui.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Uploads for hosted sessions; no access to server filesystem paths."""
2
+ from pathlib import Path
3
+
4
+ import streamlit as st
5
+
6
+ from app_environment import UPLOAD_ROOT, new_session_directory, remove_session_directory
7
+
8
+
9
+ MAX_FILE_BYTES = 1024 * 1024 * 1024
10
+ MAX_TOTAL_BYTES = 2 * MAX_FILE_BYTES
11
+
12
+
13
+ def store_uploads(files, tokenizer=None, root=UPLOAD_ROOT):
14
+ if not files:
15
+ raise ValueError('Choose a GGUF or safetensors file.')
16
+ names = [item.name for item in files]
17
+ if any(not name or '/' in name or '\\' in name or ':' in name or '\x00' in name or Path(name).name != name for name in names):
18
+ raise ValueError('Use plain file names for uploaded model files.')
19
+ if len(set(name.casefold() for name in names)) != len(names):
20
+ raise ValueError('Uploaded model files must have different names.')
21
+ if any(Path(name).suffix.lower() not in ('.gguf', '.safetensors') for name in names):
22
+ raise ValueError('Upload GGUF or safetensors weights only.')
23
+ if any(Path(name).suffix.lower() == '.gguf' for name in names) and len(files) != 1:
24
+ raise ValueError('Upload one GGUF file, or one or more safetensors shards.')
25
+ all_files = list(files) + ([tokenizer] if tokenizer is not None else [])
26
+ sizes = [len(item.getbuffer()) for item in all_files]
27
+ if any(size > MAX_FILE_BYTES for size in sizes) or sum(sizes) > MAX_TOTAL_BYTES:
28
+ raise ValueError('Uploads allow up to 1 GB per file and 2 GB in total. Use Hugging Face for larger models.')
29
+ directory = new_session_directory(root)
30
+ try:
31
+ for item in files:
32
+ with (directory / item.name).open('wb') as target:
33
+ target.write(item.getbuffer())
34
+ tokenizer_path = None
35
+ if tokenizer is not None:
36
+ tokenizer_path = directory / 'tokenizer.json'
37
+ with tokenizer_path.open('wb') as target:
38
+ target.write(tokenizer.getbuffer())
39
+ model_path = directory / names[0] if len(names) == 1 else directory
40
+ return model_path, tokenizer_path, directory
41
+ except Exception:
42
+ remove_session_directory(directory, root)
43
+ raise
44
+
45
+
46
+ def render_upload_loader(activate_model):
47
+ st.caption('Upload a single GGUF file or safetensors weights. Up to 1 GB per file, 2 GB total.')
48
+ files = st.file_uploader('Model files', type=['gguf', 'safetensors'], accept_multiple_files=True, key='uploaded_models')
49
+ tokenizer = st.file_uploader('Matching tokenizer.json (optional)', type=['json'], key='uploaded_tokenizer')
50
+ st.caption('Uploads are processed by this Space in your session and removed when you clear the model. Restarting the Space also clears uploads.')
51
+ if st.button('Load uploaded model', key='load_upload', type='primary', disabled=not files, use_container_width=True):
52
+ directory = None
53
+ try:
54
+ with st.spinner('Reading uploaded model…'):
55
+ path, tokenizer_path, directory = store_uploads(files, tokenizer)
56
+ activate_model(path, tokenizer_path, 'Uploaded: ' + ', '.join(item.name for item in files))
57
+ st.session_state.upload_directory = directory
58
+ st.rerun()
59
+ except Exception as error:
60
+ if directory is not None:
61
+ remove_session_directory(directory, UPLOAD_ROOT)
62
+ st.error(f'Could not load upload: {error}')