Skip to content

Commit

Permalink
fix: crash on startup due to importing invalid model, causing verifyM…
Browse files Browse the repository at this point in the history
…odelList to keep loading incompatible file
  • Loading branch information
Vali-98 committed Nov 27, 2024
1 parent 2b814bd commit d17bf6a
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 23 deletions.
49 changes: 31 additions & 18 deletions app/components/ModelManager/ModelItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,18 @@ const ModelItem: React.FC<ModelItemProps> = ({
const [autoLoad, setAutoLoad] = useMMKVObject<ModelDataType>(Global.LocalModel)
//@ts-ignore
const quant: string = item.quantization && GGMLNameMap[item.quantization]
const disable = modelLoading || modelImporting || modelId !== undefined
const disableDelete = modelId === item.id || modelLoading
const disableEdit = modelId === item.id || modelLoading
const isInvalid = Llama.isInitialEntry(item)

const handleDeleteModel = () => {
Alert.alert({
title: 'Delete Model',
description:
`Are you sure you want to delete "${item.name}"?\n\nThis cannot be undone!` +
(!item.file_path.startsWith('content')
? `\n\nThis operation will clear up ${readableFileSize(item.file_size)}`
(!isInvalid
? !item.file_path.startsWith('content')
? `\n\nThis operation will clear up ${readableFileSize(item.file_size)}`
: '\n\n(This will not delete external model files, just this entry)'
: ''),
buttons: [
{ label: 'Cancel' },
Expand All @@ -59,6 +60,9 @@ const ModelItem: React.FC<ModelItemProps> = ({
})
}

const disable = modelLoading || modelImporting || modelId !== undefined || isInvalid
const disableEdit = modelId === item.id || modelLoading || isInvalid

return (
<Animated.View
style={styles.modelContainer}
Expand All @@ -72,20 +76,29 @@ const ModelItem: React.FC<ModelItemProps> = ({
/>

<Text style={styles.title}>{item.name}</Text>
<View style={styles.tagContainer}>
<Text style={styles.tag}>
{item.params === 'N/A' ? 'No Param Size' : item.params}
</Text>
<Text style={styles.tag}>{quant}</Text>
<Text style={styles.tag}>{readableFileSize(item.file_size)}</Text>
<Text style={{ ...styles.tag, textTransform: 'capitalize' }}>
{item.architecture}
</Text>
<Text style={styles.tag}>
{item.file_path.startsWith('content') ? 'External' : 'Internal'}
</Text>
</View>
<Text style={styles.subtitle}>Context Length: {item.context_length}</Text>
{!isInvalid && (
<View style={styles.tagContainer}>
<Text style={styles.tag}>
{item.params === 'N/A' ? 'No Param Size' : item.params}
</Text>
<Text style={styles.tag}>{quant}</Text>
<Text style={styles.tag}>{readableFileSize(item.file_size)}</Text>
<Text style={{ ...styles.tag, textTransform: 'capitalize' }}>
{item.architecture}
</Text>
<Text style={styles.tag}>
{item.file_path.startsWith('content') ? 'External' : 'Internal'}
</Text>
</View>
)}
{isInvalid && (
<View style={styles.tagContainer}>
<Text style={styles.tag}>Model is Invalid</Text>
</View>
)}
{!isInvalid && (
<Text style={styles.subtitle}>Context Length: {item.context_length}</Text>
)}
<Text style={styles.subtitle}>File: {item.file.replace('.gguf', '')}</Text>
<View style={styles.buttonContainer}>
<TouchableOpacity
Expand Down
61 changes: 56 additions & 5 deletions app/constants/LlamaLocal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,13 +373,28 @@ export namespace Llama {

export const createModelData = async (filename: string, deleteOnFailure: boolean = false) => {
const newdir = `${model_dir}${filename}`
const initialModelEntry = {
context_length: 0,
file: filename,
file_path: newdir,
name: 'N/A',
file_size: 0,
params: 'N/A',
quantization: '-1',
architecture: 'N/A',
}
const [{ id }, ...rest] = await db
.insert(model_data)
.values(initialModelEntry)
.returning({ id: model_data.id })

try {
const modelContext = await initLlama({ model: newdir, vocab_only: true })
const modelInfo: any = modelContext.model
const modelType = modelInfo.metadata?.['general.architecture']
const fileInfo = await FS.getInfoAsync(newdir)
const modelDataEntry = {
context_length: modelInfo.metadata?.[modelType + '.context_length'] ?? '0',
context_length: modelInfo.metadata?.[modelType + '.context_length'] ?? 0,
file: filename,
file_path: newdir,
name: modelInfo.metadata?.['general.name'] ?? 'N/A',
Expand All @@ -390,8 +405,7 @@ export namespace Llama {
}
Logger.log(`New Model Data:\n${modelDataText(modelDataEntry)}`)
await modelContext.release()

await db.insert(model_data).values(modelDataEntry)
await db.update(model_data).set(modelDataEntry).where(eq(model_data.id, id))
return true
} catch (e) {
Logger.log(`Failed to create data: ${e}`, true)
Expand All @@ -409,13 +423,29 @@ export namespace Llama {
Logger.log('Filename invalid, Import Failed', true)
return
}

const initialModelEntry = {
context_length: 0,
file: filename,
file_path: newdir,
name: 'N/A',
file_size: 0,
params: 'N/A',
quantization: '-1',
architecture: 'N/A',
}
const [{ id }, ...rest] = await db
.insert(model_data)
.values(initialModelEntry)
.returning({ id: model_data.id })

try {
const modelContext = await initLlama({ model: newdir, vocab_only: true })
const modelInfo: any = modelContext.model
const modelType = modelInfo.metadata?.['general.architecture']
const fileInfo = await FS.getInfoAsync(newdir)
const modelDataEntry = {
context_length: modelInfo.metadata?.[modelType + '.context_length'] ?? '0',
context_length: modelInfo.metadata?.[modelType + '.context_length'] ?? 0,
file: filename,
file_path: newdir,
name: modelInfo.metadata?.['general.name'] ?? 'N/A',
Expand All @@ -427,7 +457,7 @@ export namespace Llama {
Logger.log(`New Model Data:\n${modelDataText(modelDataEntry)}`)
await modelContext.release()

await db.insert(model_data).values(modelDataEntry)
await db.update(model_data).set(modelDataEntry).where(eq(model_data.id, id))
return true
} catch (e) {
Logger.log(`Failed to create data: ${e}`, true)
Expand Down Expand Up @@ -493,6 +523,27 @@ export namespace Llama {
export const updateName = async (name: string, id: number) => {
await db.update(model_data).set({ name: name }).where(eq(model_data.id, id))
}

export const isInitialEntry = (data: ModelData) => {
const initial: ModelData = {
file: '',
file_path: '',
context_length: 0,
name: 'N/A',
file_size: 0,
params: 'N/A',
quantization: '-1',
architecture: 'N/A',
}

for (const key in initial) {
if (key === 'file' || key === 'file_path') continue
const initialV = initial[key as keyof ModelData]
const dataV = data[key as keyof ModelData]
if (initialV !== dataV) return false
}
return true
}
}

enum GGMLType {
Expand Down

0 comments on commit d17bf6a

Please sign in to comment.