add use cases

This commit is contained in:
gwen 2026-09-04 11:11:52 +02:00
parent a8c88a8e22
commit 1a18e372cd
8 changed files with 512 additions and 2 deletions

1
.gitignore vendored
View file

@ -6,3 +6,4 @@ overrides
bribes
site/
.obsidian
.task/

View file

@ -0,0 +1,191 @@
---
je sais utiliser ollama.py, j'ai un ordi avec 32G de RAM,
Je voudrais me mettre au Hugging Face Hub, avec des petits modèles : Qwen 2.5 0.5B pour le français, SmolLM2 360M pour langlais. Phi-3 Mini Gemma 2 2B, etc...
tu peux m'expliquer comment faire ? faut-il utiliser transformer.py de hugging face ?
---
Oui, utiliser `transformers.py` de Hugging Face est exactement la bonne approche pour charger et utiliser ces modèles. C'est la bibliothèque principale de la plateforme.
Pour te lancer avec tes modèles (Qwen 2.5 0.5B, SmolLM2 360M, etc.), voici les clés à retenir, en partant de ce que tu connais avec Ollama.
### Le cœur de la méthode : `AutoModelForCausalLM` et `AutoTokenizer`
La manière standard et la plus simple est d'utiliser les classes `AutoModelForCausalLM` et `AutoTokenizer` . Le préfixe `Auto` est pratique car il permet de charger n'importe quel modèle sans avoir à connaître sa classe exacte .
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
nom_du_modele = "Qwen/Qwen2.5-0.5B-Instruct" # Par exemple
tokenizer = AutoTokenizer.from_pretrained(nom_du_modele)
modele = AutoModelForCausalLM.from_pretrained(
nom_du_modele,
device_map="auto", # Laisse transformers gérer l'emplacement (CPU/GPU)
torch_dtype="auto" # Laisse le modèle choisir le type de données (float16, bfloat16...)
)
```
Pour un modèle comme **SmolLM2**, ce serait `"HuggingFaceTB/SmolLM2-360M-Instruct"` .
### Le rôle crucial du tokenizer
Le tokenizer ne se contente pas de découper le texte. Pour les modèles de type "Instruct" (comme ceux que tu as listés), il **doit** appliquer un *chat template*. Ce template ajoute les tokens spéciaux (comme `<|im_start|>` pour Qwen ou `<start_of_turn>` pour Gemma) qui indiquent au modèle où commence le rôle de l'utilisateur, celui de l'assistant, etc. .
C'est la méthode `apply_chat_template()` qui s'en charge :
```python
messages = [
{"role": "user", "content": "Quelle est la capitale de la France ?"}
]
# Générer le prompt formaté
prompt_formate = tokenizer.apply_chat_template(
messages,
tokenize=False, # On veut le texte, pas les IDs pour l'instant
add_generation_prompt=True # Ajoute le token pour que le modèle commence à répondre
)
# Tokenizer le prompt pour le modèle
inputs = tokenizer(prompt_formate, return_tensors="pt").to(modele.device)
```
### Générer la réponse
Enfin, on utilise la méthode `generate()` du modèle, en veillant à ne garder que la nouvelle partie générée (sans le prompt).
```python
outputs = modele.generate(**inputs, max_new_tokens=500)
# Décoder uniquement la nouvelle partie
reponse = tokenizer.decode(outputs[0][inputs['input_ids'].shape[-1]:], skip_special_tokens=True)
print(reponse)
```
### Conseils pour ton ordinateur de 32 Go de RAM
Tes choix de modèles sont parfaits pour une machine comme la tienne.
* **Les modèles très légers (0.5B, 360M)** : Ils sont conçus pour tourner sur des appareils avec des ressources limitées. Par exemple, un modèle SmolLM2 360M n'utilise qu'environ **700 Mo** de mémoire pour l'inférence . Le Qwen 2.5 0.5B est un excellent choix pour le français .
* **Optimisation pour les modèles plus gros** : Pour des modèles comme Phi-3 Mini (3.8B) ou Gemma 2 2B, tu peux utiliser la quantification (par exemple, des modèles en `4-bit` comme ceux trouvés sur le Hub) pour réduire drastiquement leur empreinte mémoire. Avec 32 Go de RAM, tu as de la marge.
* **Stabilité sur Mac (MPS)** : Si tu es sur un Mac récent avec puce M, tu pourras utiliser l'accélération GPU (`device_map="mps"`). Attention : pour un entraînement (fine-tuning), il est parfois plus stable d'utiliser le type `torch.float32` plutôt que `float16` pour éviter des erreurs de calcul (NaN) . Pour la simple inférence, ce ne sera pas un problème.
### L'alternative : `pipeline()`
Pour une prise en main encore plus rapide, la fonction `pipeline()` de Transformers est idéale . Elle gère automatiquement la tokenisation et la génération.
```python
from transformers import pipeline
generateur = pipeline("text-generation", model="Qwen/Qwen2.5-0.5B-Instruct")
resultat = generateur([{"role": "user", "content": "Bonjour !"}], max_new_tokens=100)
print(resultat[0]['generated_text'])
```
En résumé, `transformers.py` est l'outil par excellence pour tes besoins. Commence par charger un modèle, joue avec `apply_chat_template()` et `generate()`, et tu maîtriseras vite le fonctionnement.
N'hésite pas si tu as d'autres questions, par exemple sur le chargement d'un modèle quantifié pour économiser encore plus de mémoire !
---
ok et comment je fais pour être vraiment en local, c'est-à-dire avec ollama je fais un ollama pull <mon_modèle>, là je fais comment pour récupérer le modèle ?
---
Avec Hugging Face, le processus est un peu différent d'`ollama pull`. Tu ne télécharges pas un seul fichier `.gguf` comme avec Ollama, mais un dossier complet contenant le modèle, son tokenizer et sa configuration. Tu as plusieurs options, du plus automatique au plus manuel.
### 💡 Méthode 1 : Le téléchargement automatique avec `transformers`
C'est la méthode que tu as déjà vue, mais avec l'assurance que tout reste local.
Quand tu utilises `AutoModelForCausalLM.from_pretrained("nom_du_modele")`, le code va automatiquement :
1. **Vérifier le cache** : Par défaut, les modèles sont stockés dans `~/.cache/huggingface/transformers/` .
2. **Télécharger** : Si le modèle n'est pas trouvé, il sera téléchargé depuis le Hub de Hugging Face.
Pour garantir qu'il ne cherche **jamais** à se connecter à internet (même si le modèle est manquant), tu peux utiliser l'option `local_files_only=True` .
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
nom_du_modele = "Qwen/Qwen2.5-0.5B-Instruct"
# La première exécution va télécharger le modèle.
# Les suivantes le chargeront depuis le cache.
tokenizer = AutoTokenizer.from_pretrained(nom_du_modele)
modele = AutoModelForCausalLM.from_pretrained(
nom_du_modele,
device_map="auto",
torch_dtype="auto"
)
# Pour être sûr de ne jamais utiliser Internet (mode hors-ligne) :
# tokenizer = AutoTokenizer.from_pretrained(nom_du_modele, local_files_only=True)
# modele = AutoModelForCausalLM.from_pretrained(nom_du_modele, local_files_only=True)
```
Tu peux aussi personnaliser l'emplacement du cache avec le paramètre `cache_dir` ou la variable d'environnement `HF_HOME` .
### 🧩 Méthode 2 : Téléchargement via `huggingface_hub` (équivalent de `pull`)
Cette approche te donne un contrôle plus granulaire. Elle est idéale pour pré-télécharger un modèle ou pour gérer des cas particuliers comme les modèles au format GGUF .
```python
from huggingface_hub import snapshot_download
# Télécharge tout le modèle dans le dossier "./mon_dossier_qwen"
snapshot_download(
repo_id="Qwen/Qwen2.5-0.5B-Instruct",
local_dir="./mon_dossier_qwen",
local_dir_use_symlinks=False # Désactive les liens symboliques pour avoir une copie réelle
)
```
Une fois téléchargé, tu peux charger le modèle depuis ce dossier local :
```python
tokenizer = AutoTokenizer.from_pretrained("./mon_dossier_qwen")
modele = AutoModelForCausalLM.from_pretrained("./mon_dossier_qwen")
```
### 📁 Pour mémoire : La structure d'un modèle Hugging Face
Pour que `transformers` reconnaisse un modèle, son dossier doit contenir des fichiers précis :
* `config.json` : La configuration du modèle (nombre de couches, etc.) .
* `pytorch_model.bin` ou `*.safetensors` : Les poids du modèle. C'est l'équivalent du fichier `.gguf` d'Ollama .
* `tokenizer_config.json`, `vocab.json`, `merges.txt` : Les fichiers nécessaires au tokenizer .
### ⚙️ Gérer le mode hors-ligne (comme un pro)
L'option `local_files_only=True` est efficace, mais la manière standard est d'utiliser des variables d'environnement, surtout si tu prévois de travailler souvent hors-ligne .
Avant d'exécuter ton script, tu peux définir ces variables pour que **tous** les appels à la bibliothèque Hugging Face soient forcés à utiliser le cache local :
```bash
# Dans ton terminal
export HF_HUB_OFFLINE=1
export TRANSFORMERS_OFFLINE=1
```
Ou en Python :
```python
import os
os.environ["HF_HUB_OFFLINE"] = "1"
os.environ["TRANSFORMERS_OFFLINE"] = "1"
```
La différence est importante :
* `local_files_only=True` à l'appel : fonctionne bien, mais doit être passé à chaque fonction.
* `HF_HUB_OFFLINE=1` : agit comme un "kill switch" global. Même si une bibliothèque tente un téléchargement, elle échouera en levant une erreur, ce qui est parfait pour un environnement de production ou air-gappé .
### 📝 En résumé
| Action | Avec Ollama | Avec Hugging Face (transformers) |
| :--- | :--- | :--- |
| **Télécharger un modèle** | `ollama pull <modèle>` | `AutoModel.from_pretrained("<modèle>")` (télécharge et charge) OU `snapshot_download` (télécharge seulement) |
| **Charger un modèle** | `ollama run <modèle>` | `AutoModel.from_pretrained("./mon_dossier")` (si déjà téléchargé) |
| **Stockage** | `~/.ollama/models` (fichiers `.gguf`) | `~/.cache/huggingface/transformers/` |
| **Garantir le hors-ligne** | (Implicite, pas de téléchargement sans `pull`) | `local_files_only=True` ou `HF_HUB_OFFLINE=1` |
La grande force de Hugging Face est sa flexibilité : une fois que tu as téléchargé le dossier d'un modèle, il est totalement autonome. Tu peux le déplacer, le copier, et le charger sans jamais avoir à refaire de requête réseau.

View file

@ -1,9 +1,57 @@
# Tasks
## Structured output
## Choix du source
Le source rougail doit-il etre :
- en rougail (YAML) : non (la persona de rougail-ai ne connaît pas le format Rougail)
- en JSON : à tester
- en format markdown : c'est le format compréhensible par l'IA de base donc les tests partent là dessus
---
**est-ce utile ?**
## Savoir comment faire en Rougail :
- exporter en json (ça je crois que c'est dans la doc)
- faire un equivalent make_dict()
le make_dict(), c'est pour que l'ia aie les valeurs et pas seulement la structure.
Mais étant donné l'approche choisie, il n'est pas opportun de communiquer les valeurs
à rougail-ai.
Pour l'instant, on n'a pas de use case qui demande un truc du genre : tiens c'est quoi la valeur ????
en fait, si on veut une valeur il faut faire du structured output et un tool
qui appelle rougail et qui donne la valeur du moment.
!!! attention "Attention"
il ne faut surtout pas charger des valeurs dans la context window du LLM sinon
cela va perturber le reasonning il va s'emmeler les pinceaux
---
**pour la suite**
## choix des meilleurs LLM
- choisir les meilleurs LLM, qui se comportent le mieux tout en étant légers
- est-ce possible de le faire dans le navigateur ???
## Structured output et tools
Ne renvoyer **que** la variable recherchée, par exemple
`manual.https_proxy.address`, ou bien le nom de la famille
et la liste des variables dedans
Utiliser un schéma pydantic avec du structured output dessus.
## openWebUI
Tester openWebUI pour ollama, pour l'interface
---

104
doc/UseCases.md Normal file
View file

@ -0,0 +1,104 @@
# Use cases
## todo
- le 1/ n'est pas fini, il y a des règlages à faire, j'ai eu des résultats bizarres
- le 2/ n'est pas commencé
- le 3/ on verra après
## Use case 1
!!! example "Use case 1"
je veux récupérer une liste de path de variable qui a tel rôle
1/ "je veux récupérer une liste de path de variable qui a tel rôle + la compréhension de cette variable"
et aussi des explications (ce qu'elle a compris de telle ou telle partie de la conf
par exemple les explications du mode manuel.
exemple: comme le test avec la conf HTTPS.
Ce use case est presque fait, à part le fait que ce n'est pas la peine
de configurer la persona comme un storage, car il se pose des questions
byzarres ensuite.
Ce qu'on veut s'est récupérer les paths des variables
(pour ensuite les passer a une interface mais c'est un autre use case).
!!! important "Persona"
**A mettre dans la persona**
On considère comme étant une variable non seulement les variables mais
les familles aussi.
Rougail-ai rend compte des sous-groupes.
Sans la notion de famille, mais Rougail-ai explique spontanément
les variables à renseigner si tu enclenches le mode manuel par exemple.
Il faudrait deux possibilités : les paths oui, pas seulement les nom court.
Les deux en fait, les noms longs et les noms courts.
Mais les noms longs sont plus importants, parce que si on a le path on a tout le contexte derrière.
faire des tests :
- lorsque ça retourne une variable
- lorsque ça retourne une variable qui est une famille en fait
## Use Case 2
Ce 2eme usecase c'est
!!! example "Use case 2"
j'aimerais que tu m'explique ma conf
tiens tu peux m'expliquer comment est configuré le proxy chez moi ?
(Sachant qu'il ne faut même pas expliquer à rougail-ai que **c'est** une conf...)
2/ "je veux comprendre ma configuration actuelle :
ça retourne une explication textuelle + une liste de path des variables concernées"
En sortie, pour l'instant, on veut juste du texte.
On veut que rougail-ai nous explique textuellement
- la nature de la "conf"
- la liste des variables qui sont concernées
**pour le moment rougail-ai retourne la liste des path qui sont concernés**
!!! note "Rappel"
on veut que rougail-ai ne fasse rien d'opérationnel,
on veut qu'elle délègue à rougail dès qu'il y a une opération à calculer.
Mais cela c'est un autre use case.
---
**étapes ultérieures**
## Use Case 3
3/ "suggère moi une configuration permettant d'arriver à ce resultat
et il retourne une liste de path + valeur"
Rougail-ai peut décider d'ouvrir des widgets genre formulaires.
Là on est dans le "generated app".
!!! example "Exemple"
"ok ton proxy est configuré mais pas le HTTPS pour le moment si tu veux configurer le HTTPS tien voilà la liste des variables"
Au niveau de la génération des widgets, c'est déplacé dans un autre projet pour l'instant:
- l'ia lance des widgets un peu comme le faisait [zenity](https://forge.cloud.silique.fr/gremond/baklava/src/branch/main/doc/Zenity1.md)
(sur gnome)

View file

@ -1,7 +1,8 @@
# Rougail AI
## todo
## Use cases and tasks
- [[UseCases]]
- [[Tasks]]
## content
@ -10,3 +11,4 @@
- [[ChoixLllm]]
- [[ChoixLllmQuery]]
- [[Tools]]
- [[HuggingFaceGettingStarted]]

View file

@ -0,0 +1,50 @@
>>> How can I switch to manual configuration?
Thinking...
Okay, so the user is asking how to switch to manual configuration based on the provided markdown documentation. Let me break down the information from the markdown to figure out the
best way to respond.
First, looking at the markdown, there's a section under "Manual proxy configuration" which includes a note. The note says, "Disabled: when the variable 'Configure Proxy Access to the
Internet' hasn't the value 'Manual proxy configuration'." So, the variable in question is probably the one named "proxy_mode" because that's where the configuration options are set.
The user wants to switch to manual configuration, which means they need to set the "proxy_mode" variable to "Manual proxy configuration." I should explain that clearly. Also, it's good
to mention that this will allow them to configure HTTP, HTTPS, and SOCKS proxies with specific addresses and ports.
I should structure the response step-by-step to make it easy to follow. Maybe start by telling them to set the proxy_mode variable, then list the specific variables they need to
configure, and perhaps give examples of those configurations for clarity.
I should also ensure that the instructions are concise and direct, avoiding unnecessary jargon but still technical enough since it's about variables and configuration. Making sure to
highlight the key points without overwhelming them is important.
Wait, do I need to mention anything about the other options like auto or no_proxy? Probably not, since the user is asking specifically about manual configuration. But it's good to
briefly explain what the other options are for context.
Also, I should make sure that the response is helpful and guides the user on the next steps after changing the variable. Maybe suggest checking the documentation again for details on
each variable.
Putting it all together, the response should be straightforward, explaining the necessary variable change and what that entails.
...done thinking.
To switch to manual proxy configuration, you need to configure the `proxy_mode` variable to `Manual proxy configuration`. This means setting the value of the variable `<a
id="proxy_mode" name="proxy_mode">proxy_mode</a>` to `"Manual proxy configuration"`.
Once this variable is set to `"Manual proxy configuration"`, you can configure the HTTP, HTTPS, and SOCKS proxies as follows:
1. **HTTP Proxy**:
- Use the variable `<a id="manual.http_proxy.address" name="manual.http_proxy.address">manual.http_proxy.address</a>` to specify the HTTP proxy address.
- Use the variable `<a id="manual.http_proxy.port" name="manual.http_proxy.port">manual.http_proxy.port</a>` to specify the HTTP proxy port (default: 8080).
2. **HTTPS Proxy**:
- Use the variable `<a id="manual.https_proxy.address" name="manual.https_proxy.address">manual.https_proxy.address</a>` to specify the HTTPS proxy address.
- Use the variable `<a id="manual.https_proxy.port" name="manual.https_proxy.port">manual.https_proxy.port</a>` to specify the HTTPS proxy port (default: 8080).
3. **SOCKS Proxy**:
- Use the variable `<a id="manual.socks_proxy.address" name="manual.socks_proxy.address">manual.socks_proxy.address</a>` to specify the SOCKS proxy address.
- Use the variable `<a id="manual.socks_proxy.port" name="manual.socks_proxy.port">manual.socks_proxy.port</a>` to specify the SOCKS proxy port (default: 1080).
- Use the variable `<a id="manual.socks_proxy.version" name="manual.socks_proxy.version">manual.socks_proxy.version</a>` to specify the SOCKS proxy version (default: v5).
By configuring these variables, you can set up manual proxy settings for HTTP, HTTPS, and SOCKS.

View file

@ -0,0 +1,104 @@
>>> give me some information about the proxy
Thinking...
Alright, let's see. The user provided a markdown document that describes a data structure for variables related to proxy settings. They want me to act as a database that returns
information about these variables based on the user's request. The user specifically asked for information about the proxy.
First, I need to understand the structure of the data. The markdown has a root variable `proxy_mode` which is of type `choice` with several options. Each option is a node in the data
structure. For example, "No proxy" is one node, "Auto-detect proxy settings..." is another, and so on.
The user is asking for information about the proxy, which I interpret as wanting to know about the variables under the "proxy_mode" node. So, I should list all the possible values
(children) of `proxy_mode` and explain each briefly.
I should present this information in a clear and organized manner, perhaps as a list. Each value should be a subheader with its description. Since the user mentioned acting as a
database, using headings and bullet points would make the response easy to read.
I should also make sure to highlight the default value and any important details, like the note about the "disabled" state for some variables.
Finally, I need to ensure that the response is friendly and helpful, acknowledging the user's query and providing the necessary information without being too technical.
...done thinking.
The proxy-related variables are organized under the root variable **`proxy_mode`**, which is of type `choice` with the following possible values:
### 1. **No proxy** *(default)*
- **Description**: Disables proxy access entirely.
- **Note**: This is the default value.
---
### 2. **Auto-detect proxy settings for this network**
- **Description**: Automatically detects and configures proxy settings based on the current network environment.
---
### 3. **Use system proxy settings**
- **Description**: Configures the proxy to use system-provided proxy settings.
---
### 4. **Manual proxy configuration**
- **Description**: Allows manual configuration of the proxy settings.
- **Note**: This option is enabled only when `proxy_mode` is set to "Manual proxy configuration."
---
### 5. **Automatic proxy configuration URL**
- **Description**: Automatically configures the proxy settings based on a specified URL.
---
### 6. **SOCKS proxy** *(disabled by default)*
- **Description**: Configuration for SOCKS proxy settings.
- **Note**: This is a hidden variable and can be enabled by setting its corresponding variable to "manual" or "auto."
---
### 7. **HTTP Proxy**
- **Description**: Configuration for HTTP proxy settings.
- **Variables**:
- `http_proxy.address`: Mandatory, type `domainname` or IP address.
- `http_proxy.port`: Mandatory, type `port` (default: 8080).
---
### 8. **HTTPS Proxy**
- **Description**: Configuration for HTTPS proxy settings.
- **Variables**:
- `https_proxy.address`: Mandatory, type `domainname` or IP address.
- `https_proxy.port`: Mandatory, type `port` (default: same as HTTP proxy port).
- `use_for_https`: Boolean (default: true) to enable HTTPS proxy.
---
### 9. **Manual Proxy Configuration**
- **Description**: Configuration for manual proxy settings.
- **Variables**:
- `manual.http_proxy.address`: Mandatory, type `domainname` or IP address.
- `manual.http_proxy.port`: Mandatory, type `port` (default: 8080).
- `manual.use_for_https`: Boolean (default: true) to enable HTTPS proxy.
---
### 10. **SOCKS Proxy Configuration**
- **Description**: Configuration for SOCKS proxy settings.
- **Variables**:
- `manual.socks_proxy.address`: Mandatory, type `domainname` or IP address.
- `manual.socks_proxy.port`: Mandatory, type `port` (default: 1080).
- `manual.socks_proxy.version`: Choice (`v4` or `v5`, default: `v5`).
---
### 11. **Auto Proxy Configuration URL**
- **Description**: Configuration for automatic proxy settings based on a specified URL.
---
### 12. **No Proxy Address**
- **Description**: Specifies the address for which the proxy will be disabled.
---
This structure allows for flexible configuration of proxy settings, either manually, automatically, or through a combination of both.

View file

@ -0,0 +1,10 @@
Oh, and since the user is working with in-memory storage, I should mention how they can update the variables in their code. Maybe they're using a tool that allows them to write to the
storage, so I should include an example of how to set these variables programmatically.
-> pas bon du tout. TODO : enlever cette question du "in-memory storage" dans la persona ?
en même temps c'est lors d'une discussion prolongée que ça ressort.