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 { useEffect, useMemo, useState } from 'react'; | |
| import { classNames } from '../utils/misc'; | |
| import { Conversation } from '../utils/types'; | |
| import StorageUtils from '../utils/storage'; | |
| import { useNavigate, useParams } from 'react-router'; | |
| import { | |
| ArrowDownTrayIcon, | |
| EllipsisVerticalIcon, | |
| PencilIcon, | |
| PencilSquareIcon, | |
| TrashIcon, | |
| XMarkIcon, | |
| } from '@heroicons/react/24/outline'; | |
| import { BtnWithTooltips } from '../utils/common'; | |
| import { useAppContext } from '../utils/app.context'; | |
| import toast from 'react-hot-toast'; | |
| import { useModals } from './ModalProvider'; | |
| export default function Sidebar() { | |
| const params = useParams(); | |
| const navigate = useNavigate(); | |
| const { isGenerating } = useAppContext(); | |
| const [conversations, setConversations] = useState<Conversation[]>([]); | |
| const [currConv, setCurrConv] = useState<Conversation | null>(null); | |
| useEffect(() => { | |
| StorageUtils.getOneConversation(params.convId ?? '').then(setCurrConv); | |
| }, [params.convId]); | |
| useEffect(() => { | |
| const handleConversationChange = async () => { | |
| setConversations(await StorageUtils.getAllConversations()); | |
| }; | |
| StorageUtils.onConversationChanged(handleConversationChange); | |
| handleConversationChange(); | |
| return () => { | |
| StorageUtils.offConversationChanged(handleConversationChange); | |
| }; | |
| }, []); | |
| const { showConfirm, showPrompt } = useModals(); | |
| const groupedConv = useMemo( | |
| () => groupConversationsByDate(conversations), | |
| [conversations] | |
| ); | |
| return ( | |
| <> | |
| <input | |
| id="toggle-drawer" | |
| type="checkbox" | |
| className="drawer-toggle" | |
| aria-label="Toggle sidebar" | |
| defaultChecked | |
| /> | |
| <div | |
| className="drawer-side h-screen lg:h-screen z-50 lg:max-w-64" | |
| role="complementary" | |
| aria-label="Sidebar" | |
| tabIndex={0} | |
| > | |
| <label | |
| htmlFor="toggle-drawer" | |
| aria-label="Close sidebar" | |
| className="drawer-overlay" | |
| ></label> | |
| <a | |
| href="#main-scroll" | |
| className="absolute -left-80 top-0 w-1 h-1 overflow-hidden" | |
| > | |
| Skip to main content | |
| </a> | |
| <div className="flex flex-col bg-base-200 min-h-full max-w-64 py-4 px-4"> | |
| <div className="flex flex-row items-center justify-between mb-4 mt-4"> | |
| <h2 className="font-bold ml-4" role="heading"> | |
| Conversations | |
| </h2> | |
| {/* close sidebar button */} | |
| <label | |
| htmlFor="toggle-drawer" | |
| className="btn btn-ghost lg:hidden" | |
| aria-label="Close sidebar" | |
| role="button" | |
| tabIndex={0} | |
| > | |
| <XMarkIcon className="w-5 h-5" /> | |
| </label> | |
| </div> | |
| {/* new conversation button */} | |
| <button | |
| className={classNames({ | |
| 'btn btn-ghost justify-start px-2': true, | |
| 'btn-soft': !currConv, | |
| })} | |
| onClick={() => navigate('/')} | |
| aria-label="New conversation" | |
| > | |
| <PencilSquareIcon className="w-5 h-5" /> | |
| New conversation | |
| </button> | |
| {/* list of conversations */} | |
| {groupedConv.map((group, i) => ( | |
| <div key={i} role="group"> | |
| {/* group name (by date) */} | |
| {group.title ? ( | |
| // we use btn class here to make sure that the padding/margin are aligned with the other items | |
| <b | |
| className="btn btn-ghost btn-xs bg-none btn-disabled block text-xs text-base-content text-start px-2 mb-0 mt-6 font-bold" | |
| role="note" | |
| aria-description={group.title} | |
| tabIndex={0} | |
| > | |
| {group.title} | |
| </b> | |
| ) : ( | |
| <div className="h-2" /> | |
| )} | |
| {group.conversations.map((conv) => ( | |
| <ConversationItem | |
| key={conv.id} | |
| conv={conv} | |
| isCurrConv={currConv?.id === conv.id} | |
| onSelect={() => { | |
| navigate(`/chat/${conv.id}`); | |
| }} | |
| onDelete={async () => { | |
| if (isGenerating(conv.id)) { | |
| toast.error( | |
| 'Cannot delete conversation while generating' | |
| ); | |
| return; | |
| } | |
| if ( | |
| await showConfirm( | |
| 'Are you sure to delete this conversation?' | |
| ) | |
| ) { | |
| toast.success('Conversation deleted'); | |
| StorageUtils.remove(conv.id); | |
| navigate('/'); | |
| } | |
| }} | |
| onDownload={() => { | |
| if (isGenerating(conv.id)) { | |
| toast.error( | |
| 'Cannot download conversation while generating' | |
| ); | |
| return; | |
| } | |
| const conversationJson = JSON.stringify(conv, null, 2); | |
| const blob = new Blob([conversationJson], { | |
| type: 'application/json', | |
| }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = `conversation_${conv.id}.json`; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| }} | |
| onRename={async () => { | |
| if (isGenerating(conv.id)) { | |
| toast.error( | |
| 'Cannot rename conversation while generating' | |
| ); | |
| return; | |
| } | |
| const newName = await showPrompt( | |
| 'Enter new name for the conversation', | |
| conv.name | |
| ); | |
| if (newName && newName.trim().length > 0) { | |
| StorageUtils.updateConversationName(conv.id, newName); | |
| } | |
| }} | |
| /> | |
| ))} | |
| </div> | |
| ))} | |
| <div className="text-center text-xs opacity-40 mt-auto mx-4 pt-8"> | |
| Conversations are saved to browser's IndexedDB | |
| </div> | |
| </div> | |
| </div> | |
| </> | |
| ); | |
| } | |
| function ConversationItem({ | |
| conv, | |
| isCurrConv, | |
| onSelect, | |
| onDelete, | |
| onDownload, | |
| onRename, | |
| }: { | |
| conv: Conversation; | |
| isCurrConv: boolean; | |
| onSelect: () => void; | |
| onDelete: () => void; | |
| onDownload: () => void; | |
| onRename: () => void; | |
| }) { | |
| return ( | |
| <div | |
| role="menuitem" | |
| tabIndex={0} | |
| aria-label={conv.name} | |
| className={classNames({ | |
| 'group flex flex-row btn btn-ghost justify-start items-center font-normal px-2 h-9': | |
| true, | |
| 'btn-soft': isCurrConv, | |
| })} | |
| > | |
| <button | |
| key={conv.id} | |
| className="w-full overflow-hidden truncate text-start" | |
| onClick={onSelect} | |
| dir="auto" | |
| > | |
| {conv.name} | |
| </button> | |
| <div tabIndex={0} className="dropdown dropdown-end h-5"> | |
| <BtnWithTooltips | |
| // on mobile, we always show the ellipsis icon | |
| // on desktop, we only show it when the user hovers over the conversation item | |
| // we use opacity instead of hidden to avoid layout shift | |
| className="cursor-pointer opacity-100 md:opacity-0 group-hover:opacity-100" | |
| onClick={() => {}} | |
| tooltipsContent="More" | |
| > | |
| <EllipsisVerticalIcon className="w-5 h-5" /> | |
| </BtnWithTooltips> | |
| {/* dropdown menu */} | |
| <ul | |
| aria-label="More options" | |
| tabIndex={0} | |
| className="dropdown-content menu bg-base-100 rounded-box z-[1] p-2 shadow" | |
| > | |
| <li onClick={onRename} tabIndex={0}> | |
| <a> | |
| <PencilIcon className="w-4 h-4" /> | |
| Rename | |
| </a> | |
| </li> | |
| <li onClick={onDownload} tabIndex={0}> | |
| <a> | |
| <ArrowDownTrayIcon className="w-4 h-4" /> | |
| Download | |
| </a> | |
| </li> | |
| <li className="text-error" onClick={onDelete} tabIndex={0}> | |
| <a> | |
| <TrashIcon className="w-4 h-4" /> | |
| Delete | |
| </a> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| ); | |
| } | |
| // WARN: vibe code below | |
| export interface GroupedConversations { | |
| title?: string; | |
| conversations: Conversation[]; | |
| } | |
| // TODO @ngxson : add test for this function | |
| // Group conversations by date | |
| // - "Previous 7 Days" | |
| // - "Previous 30 Days" | |
| // - "Month Year" (e.g., "April 2023") | |
| export function groupConversationsByDate( | |
| conversations: Conversation[] | |
| ): GroupedConversations[] { | |
| const now = new Date(); | |
| const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); // Start of today | |
| const sevenDaysAgo = new Date(today); | |
| sevenDaysAgo.setDate(today.getDate() - 7); | |
| const thirtyDaysAgo = new Date(today); | |
| thirtyDaysAgo.setDate(today.getDate() - 30); | |
| const groups: { [key: string]: Conversation[] } = { | |
| Today: [], | |
| 'Previous 7 Days': [], | |
| 'Previous 30 Days': [], | |
| }; | |
| const monthlyGroups: { [key: string]: Conversation[] } = {}; // Key format: "Month Year" e.g., "April 2023" | |
| // Sort conversations by lastModified date in descending order (newest first) | |
| // This helps when adding to groups, but the final output order of groups is fixed. | |
| const sortedConversations = [...conversations].sort( | |
| (a, b) => b.lastModified - a.lastModified | |
| ); | |
| for (const conv of sortedConversations) { | |
| const convDate = new Date(conv.lastModified); | |
| if (convDate >= today) { | |
| groups['Today'].push(conv); | |
| } else if (convDate >= sevenDaysAgo) { | |
| groups['Previous 7 Days'].push(conv); | |
| } else if (convDate >= thirtyDaysAgo) { | |
| groups['Previous 30 Days'].push(conv); | |
| } else { | |
| const monthName = convDate.toLocaleString('default', { month: 'long' }); | |
| const year = convDate.getFullYear(); | |
| const monthYearKey = `${monthName} ${year}`; | |
| if (!monthlyGroups[monthYearKey]) { | |
| monthlyGroups[monthYearKey] = []; | |
| } | |
| monthlyGroups[monthYearKey].push(conv); | |
| } | |
| } | |
| const result: GroupedConversations[] = []; | |
| if (groups['Today'].length > 0) { | |
| result.push({ | |
| title: undefined, // no title for Today | |
| conversations: groups['Today'], | |
| }); | |
| } | |
| if (groups['Previous 7 Days'].length > 0) { | |
| result.push({ | |
| title: 'Previous 7 Days', | |
| conversations: groups['Previous 7 Days'], | |
| }); | |
| } | |
| if (groups['Previous 30 Days'].length > 0) { | |
| result.push({ | |
| title: 'Previous 30 Days', | |
| conversations: groups['Previous 30 Days'], | |
| }); | |
| } | |
| // Sort monthly groups by date (most recent month first) | |
| const sortedMonthKeys = Object.keys(monthlyGroups).sort((a, b) => { | |
| const dateA = new Date(a); // "Month Year" can be parsed by Date constructor | |
| const dateB = new Date(b); | |
| return dateB.getTime() - dateA.getTime(); | |
| }); | |
| for (const monthKey of sortedMonthKeys) { | |
| if (monthlyGroups[monthKey].length > 0) { | |
| result.push({ title: monthKey, conversations: monthlyGroups[monthKey] }); | |
| } | |
| } | |
| return result; | |
| } | |