Text Generation
Transformers
Safetensors
GGUF
llama
chatbot
multilingual
arabic
french
tamazight
english
conversational
text-generation-inference
4-bit precision
bitsandbytes
Instructions to use kaisser/LLM-Maroc with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use kaisser/LLM-Maroc with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="kaisser/LLM-Maroc") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("kaisser/LLM-Maroc") model = AutoModelForCausalLM.from_pretrained("kaisser/LLM-Maroc", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use kaisser/LLM-Maroc with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf kaisser/LLM-Maroc:BF16 # Run inference directly in the terminal: llama cli -hf kaisser/LLM-Maroc:BF16
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf kaisser/LLM-Maroc:BF16 # Run inference directly in the terminal: llama cli -hf kaisser/LLM-Maroc:BF16
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf kaisser/LLM-Maroc:BF16 # Run inference directly in the terminal: ./llama-cli -hf kaisser/LLM-Maroc:BF16
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf kaisser/LLM-Maroc:BF16 # Run inference directly in the terminal: ./build/bin/llama-cli -hf kaisser/LLM-Maroc:BF16
Use Docker
docker model run hf.co/kaisser/LLM-Maroc:BF16
- LM Studio
- Jan
- vLLM
How to use kaisser/LLM-Maroc with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "kaisser/LLM-Maroc" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "kaisser/LLM-Maroc", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/kaisser/LLM-Maroc:BF16
- SGLang
How to use kaisser/LLM-Maroc with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "kaisser/LLM-Maroc" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "kaisser/LLM-Maroc", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "kaisser/LLM-Maroc" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "kaisser/LLM-Maroc", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Ollama
How to use kaisser/LLM-Maroc with Ollama:
ollama run hf.co/kaisser/LLM-Maroc:BF16
- Unsloth Studio
How to use kaisser/LLM-Maroc with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for kaisser/LLM-Maroc to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for kaisser/LLM-Maroc to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for kaisser/LLM-Maroc to start chatting
- Docker Model Runner
How to use kaisser/LLM-Maroc with Docker Model Runner:
docker model run hf.co/kaisser/LLM-Maroc:BF16
- Lemonade
How to use kaisser/LLM-Maroc with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull kaisser/LLM-Maroc:BF16
Run and chat with the model
lemonade run user.LLM-Maroc-BF16
List all available models
lemonade list
- Atomic Chat
| import React, { createContext, useContext, useEffect, useState } from 'react'; | |
| import { | |
| APIMessage, | |
| CanvasData, | |
| Conversation, | |
| LlamaCppServerProps, | |
| Message, | |
| PendingMessage, | |
| ViewingChat, | |
| } from './types'; | |
| import StorageUtils from './storage'; | |
| import { | |
| filterThoughtFromMsgs, | |
| normalizeMsgsForAPI, | |
| getSSEStreamAsync, | |
| getServerProps, | |
| } from './misc'; | |
| import { BASE_URL, CONFIG_DEFAULT, isDev } from '../Config'; | |
| import { matchPath, useLocation, useNavigate } from 'react-router'; | |
| import toast from 'react-hot-toast'; | |
| interface AppContextValue { | |
| // conversations and messages | |
| viewingChat: ViewingChat | null; | |
| pendingMessages: Record<Conversation['id'], PendingMessage>; | |
| isGenerating: (convId: string) => boolean; | |
| sendMessage: ( | |
| convId: string | null, | |
| leafNodeId: Message['id'] | null, | |
| content: string, | |
| extra: Message['extra'], | |
| onChunk: CallbackGeneratedChunk | |
| ) => Promise<boolean>; | |
| stopGenerating: (convId: string) => void; | |
| replaceMessageAndGenerate: ( | |
| convId: string, | |
| parentNodeId: Message['id'], // the parent node of the message to be replaced | |
| content: string | null, | |
| extra: Message['extra'], | |
| onChunk: CallbackGeneratedChunk | |
| ) => Promise<void>; | |
| // canvas | |
| canvasData: CanvasData | null; | |
| setCanvasData: (data: CanvasData | null) => void; | |
| // config | |
| config: typeof CONFIG_DEFAULT; | |
| saveConfig: (config: typeof CONFIG_DEFAULT) => void; | |
| showSettings: boolean; | |
| setShowSettings: (show: boolean) => void; | |
| // props | |
| serverProps: LlamaCppServerProps | null; | |
| } | |
| // this callback is used for scrolling to the bottom of the chat and switching to the last node | |
| export type CallbackGeneratedChunk = (currLeafNodeId?: Message['id']) => void; | |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | |
| const AppContext = createContext<AppContextValue>({} as any); | |
| const getViewingChat = async (convId: string): Promise<ViewingChat | null> => { | |
| const conv = await StorageUtils.getOneConversation(convId); | |
| if (!conv) return null; | |
| return { | |
| conv: conv, | |
| // all messages from all branches, not filtered by last node | |
| messages: await StorageUtils.getMessages(convId), | |
| }; | |
| }; | |
| export const AppContextProvider = ({ | |
| children, | |
| }: { | |
| children: React.ReactElement; | |
| }) => { | |
| const { pathname } = useLocation(); | |
| const navigate = useNavigate(); | |
| const params = matchPath('/chat/:convId', pathname); | |
| const convId = params?.params?.convId; | |
| const [serverProps, setServerProps] = useState<LlamaCppServerProps | null>( | |
| null | |
| ); | |
| const [viewingChat, setViewingChat] = useState<ViewingChat | null>(null); | |
| const [pendingMessages, setPendingMessages] = useState< | |
| Record<Conversation['id'], PendingMessage> | |
| >({}); | |
| const [aborts, setAborts] = useState< | |
| Record<Conversation['id'], AbortController> | |
| >({}); | |
| const [config, setConfig] = useState(StorageUtils.getConfig()); | |
| const [canvasData, setCanvasData] = useState<CanvasData | null>(null); | |
| const [showSettings, setShowSettings] = useState(false); | |
| // get server props | |
| useEffect(() => { | |
| getServerProps(BASE_URL, config.apiKey) | |
| .then((props) => { | |
| console.debug('Server props:', props); | |
| setServerProps(props); | |
| }) | |
| .catch((err) => { | |
| console.error(err); | |
| toast.error('Failed to fetch server props'); | |
| }); | |
| // eslint-disable-next-line | |
| }, []); | |
| // handle change when the convId from URL is changed | |
| useEffect(() => { | |
| // also reset the canvas data | |
| setCanvasData(null); | |
| const handleConversationChange = async (changedConvId: string) => { | |
| if (changedConvId !== convId) return; | |
| setViewingChat(await getViewingChat(changedConvId)); | |
| }; | |
| StorageUtils.onConversationChanged(handleConversationChange); | |
| getViewingChat(convId ?? '').then(setViewingChat); | |
| return () => { | |
| StorageUtils.offConversationChanged(handleConversationChange); | |
| }; | |
| }, [convId]); | |
| const setPending = (convId: string, pendingMsg: PendingMessage | null) => { | |
| // if pendingMsg is null, remove the key from the object | |
| if (!pendingMsg) { | |
| setPendingMessages((prev) => { | |
| const newState = { ...prev }; | |
| delete newState[convId]; | |
| return newState; | |
| }); | |
| } else { | |
| setPendingMessages((prev) => ({ ...prev, [convId]: pendingMsg })); | |
| } | |
| }; | |
| const setAbort = (convId: string, controller: AbortController | null) => { | |
| if (!controller) { | |
| setAborts((prev) => { | |
| const newState = { ...prev }; | |
| delete newState[convId]; | |
| return newState; | |
| }); | |
| } else { | |
| setAborts((prev) => ({ ...prev, [convId]: controller })); | |
| } | |
| }; | |
| //////////////////////////////////////////////////////////////////////// | |
| // public functions | |
| const isGenerating = (convId: string) => !!pendingMessages[convId]; | |
| const generateMessage = async ( | |
| convId: string, | |
| leafNodeId: Message['id'], | |
| onChunk: CallbackGeneratedChunk | |
| ) => { | |
| if (isGenerating(convId)) return; | |
| const config = StorageUtils.getConfig(); | |
| const currConversation = await StorageUtils.getOneConversation(convId); | |
| if (!currConversation) { | |
| throw new Error('Current conversation is not found'); | |
| } | |
| const currMessages = StorageUtils.filterByLeafNodeId( | |
| await StorageUtils.getMessages(convId), | |
| leafNodeId, | |
| false | |
| ); | |
| const abortController = new AbortController(); | |
| setAbort(convId, abortController); | |
| if (!currMessages) { | |
| throw new Error('Current messages are not found'); | |
| } | |
| const pendingId = Date.now() + 1; | |
| let pendingMsg: PendingMessage = { | |
| id: pendingId, | |
| convId, | |
| type: 'text', | |
| timestamp: pendingId, | |
| role: 'assistant', | |
| content: null, | |
| parent: leafNodeId, | |
| children: [], | |
| }; | |
| setPending(convId, pendingMsg); | |
| try { | |
| // prepare messages for API | |
| let messages: APIMessage[] = [ | |
| ...(config.systemMessage.length === 0 | |
| ? [] | |
| : [{ role: 'system', content: config.systemMessage } as APIMessage]), | |
| ...normalizeMsgsForAPI(currMessages), | |
| ]; | |
| if (config.excludeThoughtOnReq) { | |
| messages = filterThoughtFromMsgs(messages); | |
| } | |
| if (isDev) console.log({ messages }); | |
| // prepare params | |
| const params = { | |
| messages, | |
| stream: true, | |
| cache_prompt: true, | |
| samplers: config.samplers, | |
| temperature: config.temperature, | |
| dynatemp_range: config.dynatemp_range, | |
| dynatemp_exponent: config.dynatemp_exponent, | |
| top_k: config.top_k, | |
| top_p: config.top_p, | |
| min_p: config.min_p, | |
| typical_p: config.typical_p, | |
| xtc_probability: config.xtc_probability, | |
| xtc_threshold: config.xtc_threshold, | |
| repeat_last_n: config.repeat_last_n, | |
| repeat_penalty: config.repeat_penalty, | |
| presence_penalty: config.presence_penalty, | |
| frequency_penalty: config.frequency_penalty, | |
| dry_multiplier: config.dry_multiplier, | |
| dry_base: config.dry_base, | |
| dry_allowed_length: config.dry_allowed_length, | |
| dry_penalty_last_n: config.dry_penalty_last_n, | |
| max_tokens: config.max_tokens, | |
| timings_per_token: !!config.showTokensPerSecond, | |
| ...(config.custom.length ? JSON.parse(config.custom) : {}), | |
| }; | |
| // send request | |
| const fetchResponse = await fetch(`${BASE_URL}/v1/chat/completions`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| ...(config.apiKey | |
| ? { Authorization: `Bearer ${config.apiKey}` } | |
| : {}), | |
| }, | |
| body: JSON.stringify(params), | |
| signal: abortController.signal, | |
| }); | |
| if (fetchResponse.status !== 200) { | |
| const body = await fetchResponse.json(); | |
| throw new Error(body?.error?.message || 'Unknown error'); | |
| } | |
| const chunks = getSSEStreamAsync(fetchResponse); | |
| for await (const chunk of chunks) { | |
| // const stop = chunk.stop; | |
| if (chunk.error) { | |
| throw new Error(chunk.error?.message || 'Unknown error'); | |
| } | |
| const addedContent = chunk.choices[0].delta.content; | |
| const lastContent = pendingMsg.content || ''; | |
| if (addedContent) { | |
| pendingMsg = { | |
| ...pendingMsg, | |
| content: lastContent + addedContent, | |
| }; | |
| } | |
| const timings = chunk.timings; | |
| if (timings && config.showTokensPerSecond) { | |
| // only extract what's really needed, to save some space | |
| pendingMsg.timings = { | |
| prompt_n: timings.prompt_n, | |
| prompt_ms: timings.prompt_ms, | |
| predicted_n: timings.predicted_n, | |
| predicted_ms: timings.predicted_ms, | |
| }; | |
| } | |
| setPending(convId, pendingMsg); | |
| onChunk(); // don't need to switch node for pending message | |
| } | |
| } catch (err) { | |
| setPending(convId, null); | |
| if ((err as Error).name === 'AbortError') { | |
| // user stopped the generation via stopGeneration() function | |
| // we can safely ignore this error | |
| } else { | |
| console.error(err); | |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | |
| toast.error((err as any)?.message ?? 'Unknown error'); | |
| throw err; // rethrow | |
| } | |
| } | |
| if (pendingMsg.content !== null) { | |
| await StorageUtils.appendMsg(pendingMsg as Message, leafNodeId); | |
| } | |
| setPending(convId, null); | |
| onChunk(pendingId); // trigger scroll to bottom and switch to the last node | |
| }; | |
| const sendMessage = async ( | |
| convId: string | null, | |
| leafNodeId: Message['id'] | null, | |
| content: string, | |
| extra: Message['extra'], | |
| onChunk: CallbackGeneratedChunk | |
| ): Promise<boolean> => { | |
| if (isGenerating(convId ?? '') || content.trim().length === 0) return false; | |
| if (convId === null || convId.length === 0 || leafNodeId === null) { | |
| const conv = await StorageUtils.createConversation( | |
| content.substring(0, 256) | |
| ); | |
| convId = conv.id; | |
| leafNodeId = conv.currNode; | |
| // if user is creating a new conversation, redirect to the new conversation | |
| navigate(`/chat/${convId}`); | |
| } | |
| const now = Date.now(); | |
| const currMsgId = now; | |
| StorageUtils.appendMsg( | |
| { | |
| id: currMsgId, | |
| timestamp: now, | |
| type: 'text', | |
| convId, | |
| role: 'user', | |
| content, | |
| extra, | |
| parent: leafNodeId, | |
| children: [], | |
| }, | |
| leafNodeId | |
| ); | |
| onChunk(currMsgId); | |
| try { | |
| await generateMessage(convId, currMsgId, onChunk); | |
| return true; | |
| } catch (_) { | |
| // TODO: rollback | |
| } | |
| return false; | |
| }; | |
| const stopGenerating = (convId: string) => { | |
| setPending(convId, null); | |
| aborts[convId]?.abort(); | |
| }; | |
| // if content is undefined, we remove last assistant message | |
| const replaceMessageAndGenerate = async ( | |
| convId: string, | |
| parentNodeId: Message['id'], // the parent node of the message to be replaced | |
| content: string | null, | |
| extra: Message['extra'], | |
| onChunk: CallbackGeneratedChunk | |
| ) => { | |
| if (isGenerating(convId)) return; | |
| if (content !== null) { | |
| const now = Date.now(); | |
| const currMsgId = now; | |
| StorageUtils.appendMsg( | |
| { | |
| id: currMsgId, | |
| timestamp: now, | |
| type: 'text', | |
| convId, | |
| role: 'user', | |
| content, | |
| extra, | |
| parent: parentNodeId, | |
| children: [], | |
| }, | |
| parentNodeId | |
| ); | |
| parentNodeId = currMsgId; | |
| } | |
| onChunk(parentNodeId); | |
| await generateMessage(convId, parentNodeId, onChunk); | |
| }; | |
| const saveConfig = (config: typeof CONFIG_DEFAULT) => { | |
| StorageUtils.setConfig(config); | |
| setConfig(config); | |
| }; | |
| return ( | |
| <AppContext.Provider | |
| value={{ | |
| isGenerating, | |
| viewingChat, | |
| pendingMessages, | |
| sendMessage, | |
| stopGenerating, | |
| replaceMessageAndGenerate, | |
| canvasData, | |
| setCanvasData, | |
| config, | |
| saveConfig, | |
| showSettings, | |
| setShowSettings, | |
| serverProps, | |
| }} | |
| > | |
| {children} | |
| </AppContext.Provider> | |
| ); | |
| }; | |
| export const useAppContext = () => useContext(AppContext); | |