diff --git a/MyIA.AI.Notebooks/GenAI/Image/04-Applications/04-4-Cross-Stitch-Pattern-Maker-Legacy.ipynb b/MyIA.AI.Notebooks/GenAI/Image/04-Applications/04-4-Cross-Stitch-Pattern-Maker-Legacy.ipynb index 8e6bc541f3..b7e039ff66 100644 --- a/MyIA.AI.Notebooks/GenAI/Image/04-Applications/04-4-Cross-Stitch-Pattern-Maker-Legacy.ipynb +++ b/MyIA.AI.Notebooks/GenAI/Image/04-Applications/04-4-Cross-Stitch-Pattern-Maker-Legacy.ipynb @@ -5,14 +5,15 @@ "id": "2cef15e5", "metadata": { "papermill": { - "duration": 0.007332, - "end_time": "2026-07-27T16:44:37.455432", + "duration": 0.003258, + "end_time": "2026-09-05T11:46:50.815102", "exception": false, - "start_time": "2026-07-27T16:44:37.448100", + "start_time": "2026-09-05T11:46:50.811844", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "**Navigation** : [Index](../../README.md) | [<< Précédent](04-3-Production-Integration.ipynb)\n", "\n", @@ -43,14 +44,15 @@ "id": "f8t8qfwlmdl", "metadata": { "papermill": { - "duration": 0.001986, - "end_time": "2026-07-27T16:44:37.463684", + "duration": 0.003506, + "end_time": "2026-09-05T11:46:50.822614", "exception": false, - "start_time": "2026-07-27T16:44:37.461698", + "start_time": "2026-09-05T11:46:50.819108", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "Une fois les dépendances installées, on charge la configuration de l'environnement et on définit l'URL de l'API Stable Diffusion locale. Cette séparation permet de modifier les paramètres de connexion sans toucher au code de traitement." ] @@ -61,21 +63,19 @@ "id": "aa3aa989", "metadata": { "execution": { - "iopub.execute_input": "2026-08-08T05:37:35.546759Z", - "iopub.status.busy": "2026-08-08T05:37:35.545649Z", - "iopub.status.idle": "2026-08-08T05:37:35.554943Z", - "shell.execute_reply": "2026-08-08T05:37:35.554295Z" + "iopub.execute_input": "2026-09-05T11:46:50.829792Z", + "iopub.status.busy": "2026-09-05T11:46:50.829792Z", + "iopub.status.idle": "2026-09-05T11:46:50.833948Z", + "shell.execute_reply": "2026-09-05T11:46:50.833948Z" }, "papermill": { - "duration": 0.007234, - "end_time": "2026-07-27T16:44:37.473172", + "duration": 0.009671, + "end_time": "2026-09-05T11:46:50.834952", "exception": false, - "start_time": "2026-07-27T16:44:37.465938", + "start_time": "2026-09-05T11:46:50.825281", "status": "completed" }, - "tags": [ - "parameters" - ] + "tags": [] }, "outputs": [], "source": [ @@ -89,21 +89,19 @@ "id": "dbed0095", "metadata": { "execution": { - "iopub.execute_input": "2026-08-08T05:37:35.558714Z", - "iopub.status.busy": "2026-08-08T05:37:35.558045Z", - "iopub.status.idle": "2026-08-08T05:37:35.567333Z", - "shell.execute_reply": "2026-08-08T05:37:35.565099Z" + "iopub.execute_input": "2026-09-05T11:46:50.842465Z", + "iopub.status.busy": "2026-09-05T11:46:50.841466Z", + "iopub.status.idle": "2026-09-05T11:46:50.844463Z", + "shell.execute_reply": "2026-09-05T11:46:50.844463Z" }, "papermill": { - "duration": 0.006827, - "end_time": "2026-07-27T16:44:37.481852", + "duration": 0.00651, + "end_time": "2026-09-05T11:46:50.844463", "exception": false, - "start_time": "2026-07-27T16:44:37.475025", + "start_time": "2026-09-05T11:46:50.837953", "status": "completed" }, - "tags": [ - "injected-parameters" - ] + "tags": [] }, "outputs": [], "source": [ @@ -116,14 +114,15 @@ "id": "53286701", "metadata": { "papermill": { - "duration": 0.001948, - "end_time": "2026-07-27T16:44:37.486317", + "duration": 0.003504, + "end_time": "2026-09-05T11:46:50.851512", "exception": false, - "start_time": "2026-07-27T16:44:37.484369", + "start_time": "2026-09-05T11:46:50.848008", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "### Verification des dependances et chargement des ressources\n", "\n", @@ -136,16 +135,16 @@ "id": "1c07097f", "metadata": { "execution": { - "iopub.execute_input": "2026-08-08T05:37:35.571122Z", - "iopub.status.busy": "2026-08-08T05:37:35.570912Z", - "iopub.status.idle": "2026-08-08T05:37:35.793533Z", - "shell.execute_reply": "2026-08-08T05:37:35.792998Z" + "iopub.execute_input": "2026-09-05T11:46:50.858516Z", + "iopub.status.busy": "2026-09-05T11:46:50.858516Z", + "iopub.status.idle": "2026-09-05T11:46:51.090615Z", + "shell.execute_reply": "2026-09-05T11:46:51.090112Z" }, "papermill": { - "duration": 0.252347, - "end_time": "2026-07-27T16:44:37.740614", + "duration": 0.236098, + "end_time": "2026-09-05T11:46:51.090615", "exception": false, - "start_time": "2026-07-27T16:44:37.488267", + "start_time": "2026-09-05T11:46:50.854517", "status": "completed" }, "tags": [] @@ -224,23 +223,36 @@ "from IPython.display import display\n", "import ipywidgets as widgets\n", "\n", - "# Chargement du fichier local DMC_colors.json\n", - "# Chercher dans plusieurs emplacements possibles\n", - "dmc_paths = [\n", - " \"DMC_colors.json\",\n", - " os.path.join(os.path.dirname(os.path.abspath(\".\")), \"..\", \"assets\", \"models\", \"DMC_colors.json\"),\n", - " \"../../assets/models/DMC_colors.json\",\n", - "]\n", + "# Chargement du fichier local DMC_colors.json (recherche robuste au cwd)\n", + "# Le cwd de Papermill differe du repertoire du notebook : on remonte les\n", + "# parents jusqu'a trouver assets/models/DMC_colors.json sous le depot, avec\n", + "# repli sur un DMC_colors.json immediatement local.\n", + "from pathlib import Path\n", "\n", "DMC_COLORS = []\n", - "for dmc_path in dmc_paths:\n", - " try:\n", - " with open(dmc_path, \"r\", encoding=\"utf-8\") as f:\n", - " DMC_COLORS = json.load(f)\n", - " print(f\"Nombre de references DMC chargees : {len(DMC_COLORS)} (depuis {os.path.basename(dmc_path)})\")\n", + "dmc_path = None\n", + "current_dir = Path.cwd()\n", + "for _ in range(10):\n", + " candidate = current_dir / \"assets\" / \"models\" / \"DMC_colors.json\"\n", + " if candidate.exists():\n", + " dmc_path = candidate\n", + " break\n", + " candidate = current_dir / \"MyIA.AI.Notebooks\" / \"GenAI\" / \"assets\" / \"models\" / \"DMC_colors.json\"\n", + " if candidate.exists():\n", + " dmc_path = candidate\n", + " break\n", + " direct = current_dir / \"DMC_colors.json\"\n", + " if direct.exists():\n", + " dmc_path = direct\n", + " break\n", + " current_dir = current_dir.parent\n", + " if len(current_dir.parts) <= 1:\n", " break\n", - " except FileNotFoundError:\n", - " continue\n", + "\n", + "if dmc_path is not None:\n", + " with open(dmc_path, \"r\", encoding=\"utf-8\") as f:\n", + " DMC_COLORS = json.load(f)\n", + " print(f\"Nombre de references DMC chargees : {len(DMC_COLORS)} (depuis {os.path.basename(str(dmc_path))})\")\n", "\n", "if not DMC_COLORS:\n", " print(\"Fichier DMC_colors.json non trouve. Veuillez verifier son emplacement.\")\n" @@ -251,14 +263,15 @@ "id": "33aedda3", "metadata": { "papermill": { - "duration": 0.00197, - "end_time": "2026-07-27T16:44:37.744933", + "duration": 0.003507, + "end_time": "2026-09-05T11:46:51.097755", "exception": false, - "start_time": "2026-07-27T16:44:37.742963", + "start_time": "2026-09-05T11:46:51.094248", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "## Paramètres de génération (img2img)\n", "\n", @@ -277,16 +290,16 @@ "id": "2a3da1fb", "metadata": { "execution": { - "iopub.execute_input": "2026-08-08T05:37:35.795539Z", - "iopub.status.busy": "2026-08-08T05:37:35.795306Z", - "iopub.status.idle": "2026-08-08T05:37:35.800291Z", - "shell.execute_reply": "2026-08-08T05:37:35.799739Z" + "iopub.execute_input": "2026-09-05T11:46:51.104339Z", + "iopub.status.busy": "2026-09-05T11:46:51.104339Z", + "iopub.status.idle": "2026-09-05T11:46:51.115305Z", + "shell.execute_reply": "2026-09-05T11:46:51.115305Z" }, "papermill": { - "duration": 0.008671, - "end_time": "2026-07-27T16:44:37.755526", + "duration": 0.015978, + "end_time": "2026-09-05T11:46:51.116318", "exception": false, - "start_time": "2026-07-27T16:44:37.746855", + "start_time": "2026-09-05T11:46:51.100340", "status": "completed" }, "tags": [] @@ -296,58 +309,46 @@ "name": "stdout", "output_type": "stream", "text": [ - "WARNING: .env non trouve, utilisation variables environnement\n" + ".env charge depuis: .env\n", + "SD_BASE_URL definie dans la configuration gitignoree (.env), valeur non affichee.\n" ] } ], "source": [ + "# Chargement explicite de la configuration gitignoree (MyIA.AI.Notebooks/GenAI/.env).\n", + "# Remontee des parents depuis le cwd : le cwd de Papermill differe du repertoire\n", + "# du notebook. La valeur de SD_BASE_URL n'est pas affichee (url d'infrastructure),\n", + "# seul son statut l'est. La validation (RuntimeError si absente) a lieu dans la\n", + "# cellule 10 UNIQUEMENT en mode interactif, parce que le mode batch\n", + "# (BATCH_MODE=true) utilise un fallback pédagogique local numpy qui ne contacte\n", + "# jamais Forge (cf acceptance #14581 et concern #3 #14593). Pour une exécution\n", + "# Forge end-to-end, déclarer SD_BASE_URL dans MyIA.AI.Notebooks/GenAI/.env avec\n", + "# l'URL du service déployé.\n", + "# Cf issue #14581, #14593.\n", "from pathlib import Path\n", "from dotenv import load_dotenv\n", - "import os\n", - "\n", - "# Paramètre de base pour l'endpoint Stable Diffusion\n", "\n", - "# Chargement des variables d'environnement depuis .env\n", - "# Chargement robuste de la configuration .env\n", - "from dotenv import load_dotenv\n", - "import os\n", - "# Recherche du .env dans tous les parents (pour Papermill qui change le cwd)\n", - "current_path = Path.cwd()\n", "env_loaded = False\n", + "current_dir = Path.cwd()\n", "for _ in range(10):\n", - " env_path = current_path / \".env\"\n", + " env_path = current_dir / \".env\"\n", " if env_path.exists():\n", " load_dotenv(env_path)\n", " print(f\".env charge depuis: {env_path.name}\")\n", " env_loaded = True\n", " break\n", - " current_path = current_path.parent\n", - " if len(current_path.parts) <= 1:\n", + " current_dir = current_dir.parent\n", + " if len(current_dir.parts) <= 1:\n", " break\n", "if not env_loaded:\n", " print(\"WARNING: .env non trouve, utilisation variables environnement\")\n", "\n", - "# Récupération de l'URL de l'API Stable Diffusion depuis .env\n", - "SD_BASE_URL = os.getenv(\"SD_BASE_URL\", \"https://stable-diffusion-webui-forge.yourdomain.com\")\n", - "\n", - "# Construct the full API URL by appending the endpoint path\n", - "SD_API_URL = f\"{SD_BASE_URL}/sdapi/v1/img2img\"\n", - "\n", - "# Paramètres par défaut pour la requête (vous pouvez les affiner à la demande)\n", - "default_img2img_payload = {\n", - " \"prompt\": \" Pixel Art\",\n", - " \"steps\": 20,\n", - " \"sampler_name\": \"DPM++ 2M SDE\",\n", - " \"scheduler\": \"karras\",\n", - " \"cfg_scale\": 7.5,\n", - " \"width\": 1024,\n", - " \"height\": 1024,\n", - " \"denoising_strength\": 0.37,\n", - " \"override_settings\": {\n", - " \"sd_model_checkpoint\": \"sd_xl_base_1.0\"\n", - " },\n", - " # \"seed\": 2096377536\n", - "}" + "SD_BASE_URL = os.getenv(\"SD_BASE_URL\")\n", + "if SD_BASE_URL:\n", + " print(\"SD_BASE_URL definie dans la configuration gitignoree (.env), valeur non affichee.\")\n", + "else:\n", + " print(\"SD_BASE_URL non defini : mode batch pedagogique (pas d'appel Forge) attendu,\")\n", + " print(\"ou mode interactif qui echouera en cellule 10 si BATCH_MODE n'est pas active.\")\n" ] }, { @@ -355,14 +356,15 @@ "id": "hkh4qfflabt", "metadata": { "papermill": { - "duration": 0.002155, - "end_time": "2026-07-27T16:44:37.759920", + "duration": 0.003681, + "end_time": "2026-09-05T11:46:51.122998", "exception": false, - "start_time": "2026-07-27T16:44:37.757765", + "start_time": "2026-09-05T11:46:51.119317", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "L'interface d'upload envoie l'image sélectionnée à l'endpoint Stable Diffusion img2img pour la transformer en pixel art. La boucle événementielle Jupyter gère l'attente asynchrone de la réponse tout en maintenant l'interface interactive." ] @@ -372,14 +374,15 @@ "id": "6c3438d8", "metadata": { "papermill": { - "duration": 0.002021, - "end_time": "2026-07-27T16:44:37.764029", + "duration": 0.003546, + "end_time": "2026-09-05T11:46:51.129550", "exception": false, - "start_time": "2026-07-27T16:44:37.762008", + "start_time": "2026-09-05T11:46:51.126004", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "### Upload de l’image\n", "\n", @@ -400,16 +403,16 @@ "id": "4ccd0538", "metadata": { "execution": { - "iopub.execute_input": "2026-08-08T05:37:35.801973Z", - "iopub.status.busy": "2026-08-08T05:37:35.801828Z", - "iopub.status.idle": "2026-08-08T05:37:35.812908Z", - "shell.execute_reply": "2026-08-08T05:37:35.812380Z" + "iopub.execute_input": "2026-09-05T11:46:51.136760Z", + "iopub.status.busy": "2026-09-05T11:46:51.136760Z", + "iopub.status.idle": "2026-09-05T11:46:51.150684Z", + "shell.execute_reply": "2026-09-05T11:46:51.150684Z" }, "papermill": { - "duration": 0.016171, - "end_time": "2026-07-27T16:44:37.782290", + "duration": 0.019139, + "end_time": "2026-09-05T11:46:51.151689", "exception": false, - "start_time": "2026-07-27T16:44:37.766119", + "start_time": "2026-09-05T11:46:51.132550", "status": "completed" }, "tags": [] @@ -419,7 +422,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Mode BATCH active : Creation d'une image de test palette riche.\n", + "Mode BATCH active : FALLBACK PEDAGOGIQUE LOCAL (pas d'appel Forge).\n", + "Pour une execution Forge reelle, basculer en mode interactif sans BATCH_MODE.\n", "Image de test generee (192x128, 6 regions colorees).\n" ] } @@ -429,7 +433,17 @@ "import os\n", "import numpy as np\n", "\n", - "# Detection du mode batch : Papermill injecte BATCH_MODE via la cellule parameters\n", + "# =====================================================================\n", + "# Construction de l'URL API et du payload img2img (acceptance #14581, #14593)\n", + "# =====================================================================\n", + "# Note : ces deux variables ne sont construites QUE dans la branche interactive\n", + "# (le mode batch ci-dessous utilise un fallback pédagogique local numpy et ne\n", + "# contacte jamais Forge -- voir commentaire `Mode batch` plus bas).\n", + "SD_API_URL = None\n", + "default_img2img_payload = None\n", + "\n", + "# Detection du mode batch : Papermill injecte BATCH_MODE via env var ou via\n", + "# cellule parameters.\n", "if 'notebook_mode' not in globals() or notebook_mode == \"interactive\":\n", " if 'BATCH_MODE' in globals() and BATCH_MODE.lower() in (\"true\", \"batch\"):\n", " notebook_mode = \"batch\"\n", @@ -438,6 +452,39 @@ " if notebook_mode == \"true\":\n", " notebook_mode = \"batch\"\n", "\n", + "# Construire l'URL et le payload uniquement en mode interactif. En mode batch,\n", + "# la branche `if notebook_mode in (\"batch\", \"test\"):` plus bas genere une\n", + "# image numpy locale et n'invoque jamais requests.post -- c'est un fallback\n", + "# pedagogique explicite (acceptance #14581, #14593 concern #3). La garde\n", + "# RuntimeError leve donc UNIQUEMENT en mode interactif, pas en batch --\n", + "# un etudiant en local qui n'a pas Forge doit pouvoir executer le notebook.\n", + "if notebook_mode not in (\"batch\", \"test\"):\n", + " if not SD_BASE_URL:\n", + " raise RuntimeError(\n", + " \"Mode interactif exige SD_BASE_URL declare (cf cellule 7 et \"\n", + " \"acceptance #14581). Bascule en mode batch (export BATCH_MODE=true) \"\n", + " \"si tu veux un parcours pedagogique sans Forge.\"\n", + " )\n", + " SD_API_URL = f\"{SD_BASE_URL}/sdapi/v1/img2img\"\n", + " # Payload img2img specialise (restaure, cf review adjoint 2026-09-05 delta 3).\n", + " # Pipeline \"pixel art\" : checkpoint SDXL base 1.0, LoRA pixelbuildings128-v2,\n", + " # 1024x1024, DPM++ 2M SDE + scheduler karras (parametrage historique du\n", + " # notebook). Le rendu sera valide visuellement lors du run Forge (#14617).\n", + " default_img2img_payload = {\n", + " \"prompt\": \" Pixel Art\",\n", + " \"steps\": 20,\n", + " \"sampler_name\": \"DPM++ 2M SDE\",\n", + " \"scheduler\": \"karras\",\n", + " \"cfg_scale\": 7.5,\n", + " \"width\": 1024,\n", + " \"height\": 1024,\n", + " \"denoising_strength\": 0.37,\n", + " \"override_settings\": {\n", + " \"sd_model_checkpoint\": \"sd_xl_base_1.0\"\n", + " },\n", + " # \"seed\": 2096377536\n", + " }\n", + "\n", "# ========================\n", "# Variables de controle\n", "# ========================\n", @@ -448,10 +495,19 @@ "generated_image = None\n", "\n", "# ========================\n", - "# Mode batch : creer une image de test et passer directement\n", + "# Mode batch : FALLBACK PEDAGOGIQUE LOCAL (pas d'appel Forge)\n", "# ========================\n", + "# Ce mode ne contacte JAMAIS le service Stable Diffusion Forge. Il genere une\n", + "# image numpy locale (ciel/soleil/herbe/tige/petales/coeur) puis execute le\n", + "# pipeline aval (quantification palette, matching DMC, etc.) sur cette image\n", + "# locale. C'est un parcours pedagogique sans GPU, sans service deploye, sans\n", + "# authentification : le notebook reste executable end-to-end en local pour\n", + "# valider la chaine de traitement. Pour une execution Forge reelle (img2img\n", + "# distant avec QA vision), utiliser le mode interactif sans BATCH_MODE et\n", + "# avec SD_BASE_URL declare dans .env. Cf acceptance #14581 + concern #3 #14593.\n", "if notebook_mode in (\"batch\", \"test\"):\n", - " print(f\"Mode {notebook_mode.upper()} active : Creation d'une image de test palette riche.\")\n", + " print(f\"Mode {notebook_mode.upper()} active : FALLBACK PEDAGOGIQUE LOCAL (pas d'appel Forge).\")\n", + " print(\"Pour une execution Forge reelle, basculer en mode interactif sans BATCH_MODE.\")\n", " \n", " # Image de test 192x128 (multiple de 8) avec 6 grandes regions colorees\n", " # pour exercer la quantification palette + matching DMC. Anciennement un\n", @@ -486,7 +542,7 @@ "\n", "else:\n", " # ========================\n", - " # Mode interactif avec widgets\n", + " # Mode interactif : appel Forge reel (img2img)\n", " # ========================\n", " from jupyter_ui_poll import ui_events\n", " import ipywidgets as widgets\n", @@ -546,6 +602,8 @@ " print(\"Veuillez d'abord uploader une image.\")\n", " return\n", "\n", + " # SD_API_URL et default_img2img_payload sont construits en haut de cette\n", + " # cellule (branche interactive). RuntimeError leve si SD_BASE_URL manque.\n", " payload = default_img2img_payload.copy()\n", " payload[\"init_images\"] = [encoded_init_image]\n", " payload[\"n_iter\"] = 1\n", @@ -613,7 +671,7 @@ " poll(1)\n", " time.sleep(0.1)\n", "\n", - " print(\"Generation terminee !\")" + " print(\"Generation terminee !\")\n" ] }, { @@ -621,14 +679,15 @@ "id": "97795f54", "metadata": { "papermill": { - "duration": 0.003074, - "end_time": "2026-07-27T16:44:37.787643", + "duration": 0.003508, + "end_time": "2026-09-05T11:46:51.158727", "exception": false, - "start_time": "2026-07-27T16:44:37.784569", + "start_time": "2026-09-05T11:46:51.155219", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "### Réduction de l’image en blocs de 8×8\n", "\n", @@ -649,16 +708,16 @@ "id": "cf535356", "metadata": { "execution": { - "iopub.execute_input": "2026-08-08T05:37:35.814751Z", - "iopub.status.busy": "2026-08-08T05:37:35.814558Z", - "iopub.status.idle": "2026-08-08T05:37:35.832562Z", - "shell.execute_reply": "2026-08-08T05:37:35.832061Z" + "iopub.execute_input": "2026-09-05T11:46:51.166732Z", + "iopub.status.busy": "2026-09-05T11:46:51.165732Z", + "iopub.status.idle": "2026-09-05T11:46:51.183737Z", + "shell.execute_reply": "2026-09-05T11:46:51.183737Z" }, "papermill": { - "duration": 0.050284, - "end_time": "2026-07-27T16:44:37.840247", + "duration": 0.022006, + "end_time": "2026-09-05T11:46:51.183737", "exception": false, - "start_time": "2026-07-27T16:44:37.789963", + "start_time": "2026-09-05T11:46:51.161731", "status": "completed" }, "tags": [] @@ -723,14 +782,15 @@ "id": "e0849712", "metadata": { "papermill": { - "duration": 0.002204, - "end_time": "2026-07-27T16:44:37.844908", + "duration": 0.003515, + "end_time": "2026-09-05T11:46:51.191529", "exception": false, - "start_time": "2026-07-27T16:44:37.842704", + "start_time": "2026-09-05T11:46:51.188014", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "### Exercice 1 : Analyse de la reduction par blocs\n", "\n", @@ -752,16 +812,16 @@ "id": "8c187a3a", "metadata": { "execution": { - "iopub.execute_input": "2026-08-08T05:37:35.834194Z", - "iopub.status.busy": "2026-08-08T05:37:35.834006Z", - "iopub.status.idle": "2026-08-08T05:37:35.838199Z", - "shell.execute_reply": "2026-08-08T05:37:35.837516Z" + "iopub.execute_input": "2026-09-05T11:46:51.200114Z", + "iopub.status.busy": "2026-09-05T11:46:51.200114Z", + "iopub.status.idle": "2026-09-05T11:46:51.204884Z", + "shell.execute_reply": "2026-09-05T11:46:51.204309Z" }, "papermill": { - "duration": 0.007084, - "end_time": "2026-07-27T16:44:37.854351", + "duration": 0.010627, + "end_time": "2026-09-05T11:46:51.205395", "exception": false, - "start_time": "2026-07-27T16:44:37.847267", + "start_time": "2026-09-05T11:46:51.194768", "status": "completed" }, "tags": [] @@ -807,14 +867,15 @@ "id": "exvjkyh0aae", "metadata": { "papermill": { - "duration": 0.002445, - "end_time": "2026-07-27T16:44:37.859209", + "duration": 0.0037, + "end_time": "2026-09-05T11:46:51.212779", "exception": false, - "start_time": "2026-07-27T16:44:37.856764", + "start_time": "2026-09-05T11:46:51.209079", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "Le matching des couleurs DMC associe chaque pixel réduit au fil le plus proche par distance euclidienne dans l'espace RGB. Cette étape exploite le fichier `DMC_colors.json` et produit la table d'index de couleurs nécessaire à la génération de la grille finale." ] @@ -824,14 +885,15 @@ "id": "401e10f7", "metadata": { "papermill": { - "duration": 0.002522, - "end_time": "2026-07-27T16:44:37.864226", + "duration": 0.003718, + "end_time": "2026-09-05T11:46:51.219597", "exception": false, - "start_time": "2026-07-27T16:44:37.861704", + "start_time": "2026-09-05T11:46:51.215879", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "### Matching des couleurs et conversion vers la palette DMC\n", "\n", @@ -849,16 +911,16 @@ "id": "de627f6c", "metadata": { "execution": { - "iopub.execute_input": "2026-08-08T05:37:35.839810Z", - "iopub.status.busy": "2026-08-08T05:37:35.839673Z", - "iopub.status.idle": "2026-08-08T05:37:35.849559Z", - "shell.execute_reply": "2026-08-08T05:37:35.849131Z" + "iopub.execute_input": "2026-09-05T11:46:51.227616Z", + "iopub.status.busy": "2026-09-05T11:46:51.227024Z", + "iopub.status.idle": "2026-09-05T11:46:51.239673Z", + "shell.execute_reply": "2026-09-05T11:46:51.239087Z" }, "papermill": { - "duration": 0.018242, - "end_time": "2026-07-27T16:44:37.884859", + "duration": 0.016889, + "end_time": "2026-09-05T11:46:51.239673", "exception": false, - "start_time": "2026-07-27T16:44:37.866617", + "start_time": "2026-09-05T11:46:51.222784", "status": "completed" }, "tags": [] @@ -968,14 +1030,15 @@ "id": "36e225bb", "metadata": { "papermill": { - "duration": 0.002476, - "end_time": "2026-07-27T16:44:37.890540", + "duration": 0.002536, + "end_time": "2026-09-05T11:46:51.246214", "exception": false, - "start_time": "2026-07-27T16:44:37.888064", + "start_time": "2026-09-05T11:46:51.243678", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "### Exercice 2 : Statistiques de la palette DMC\n", "\n", @@ -997,16 +1060,16 @@ "id": "b900050c", "metadata": { "execution": { - "iopub.execute_input": "2026-08-08T05:37:35.850973Z", - "iopub.status.busy": "2026-08-08T05:37:35.850800Z", - "iopub.status.idle": "2026-08-08T05:37:35.854143Z", - "shell.execute_reply": "2026-08-08T05:37:35.853604Z" + "iopub.execute_input": "2026-09-05T11:46:51.254646Z", + "iopub.status.busy": "2026-09-05T11:46:51.254646Z", + "iopub.status.idle": "2026-09-05T11:46:51.257594Z", + "shell.execute_reply": "2026-09-05T11:46:51.257594Z" }, "papermill": { - "duration": 0.010188, - "end_time": "2026-07-27T16:44:37.903862", + "duration": 0.007587, + "end_time": "2026-09-05T11:46:51.257594", "exception": false, - "start_time": "2026-07-27T16:44:37.893674", + "start_time": "2026-09-05T11:46:51.250007", "status": "completed" }, "tags": [] @@ -1049,16 +1112,17 @@ "id": "o27fyaluiz", "metadata": { "papermill": { - "duration": 0.003855, - "end_time": "2026-07-27T16:44:37.912229", + "duration": 0.003504, + "end_time": "2026-09-05T11:46:51.264930", "exception": false, - "start_time": "2026-07-27T16:44:37.908374", + "start_time": "2026-09-05T11:46:51.261426", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ - "---\n", + "***\n", "\n", "## Exercice : Générateur Complet de Patron de Point de Croix avec Export\n", "\n", @@ -1243,14 +1307,15 @@ "id": "de0293d5", "metadata": { "papermill": { - "duration": 0.002614, - "end_time": "2026-07-27T16:44:37.917453", + "duration": 0.003165, + "end_time": "2026-09-05T11:46:51.271107", "exception": false, - "start_time": "2026-07-27T16:44:37.914839", + "start_time": "2026-09-05T11:46:51.267942", "status": "completed" }, "tags": [] }, + "outputs": [], "source": [ "### Exercice 3 : Redimensionnement adaptatif avec conservation des proportions\n", "\n", @@ -1272,16 +1337,16 @@ "id": "cedaabe5", "metadata": { "execution": { - "iopub.execute_input": "2026-08-08T05:37:35.855857Z", - "iopub.status.busy": "2026-08-08T05:37:35.855726Z", - "iopub.status.idle": "2026-08-08T05:37:35.859108Z", - "shell.execute_reply": "2026-08-08T05:37:35.858537Z" + "iopub.execute_input": "2026-09-05T11:46:51.279632Z", + "iopub.status.busy": "2026-09-05T11:46:51.279632Z", + "iopub.status.idle": "2026-09-05T11:46:51.282778Z", + "shell.execute_reply": "2026-09-05T11:46:51.282778Z" }, "papermill": { - "duration": 0.008906, - "end_time": "2026-07-27T16:44:37.929461", + "duration": 0.008152, + "end_time": "2026-09-05T11:46:51.283783", "exception": false, - "start_time": "2026-07-27T16:44:37.920555", + "start_time": "2026-09-05T11:46:51.275631", "status": "completed" }, "tags": [] @@ -1317,23 +1382,6 @@ } ], "metadata": { - "cost": { - "api_provider": "stability", - "api_usd_est": 0.2, - "cpu_min": 2, - "external_account": "stability", - "free_alternative": "GenAI/Image/01-Foundation/01-4-Forge-SD-XL-Turbo.ipynb", - "gpu_min": 0, - "gpu_required": false, - "metadata_written": "2026-07-23T08:45Z", - "network": true, - "notes": "Notebook LEGACY : transformation image vers patron de point de croix.\nPipeline : upload image → Stable Diffusion API (pixel art) → reduction palette DMC → grille.\nPalette DMC : fichier JSON local (pas d'API).\nCout reel depend du nombre d'iterations Stable Diffusion (~5-10 par demo).\nAlternative gratuite : Forge SD XL Turbo local (pas de cle API).", - "reduced_pedagogical": "GenAI/Image/01-Foundation/01-3-Basic-Image-Operations.ipynb", - "reproducibility": "LOW", - "validator": "papermill", - "vram_gb": 0, - "vram_tier": "LITE" - }, "kernelspec": { "display_name": "Python 3", "language": "python", @@ -1349,36 +1397,22 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.14" + "version": "3.11.9" }, "papermill": { "default_parameters": {}, - "duration": 2.99736, - "end_time": "2026-07-27T16:44:38.179006", + "duration": 2.057506, + "end_time": "2026-09-05T11:46:51.528537", "environment_variables": {}, "exception": null, "input_path": "04-4-Cross-Stitch-Pattern-Maker-Legacy.ipynb", - "output_path": "04-4-Cross-Stitch-Pattern-Maker-Legacy_output.ipynb", + "output_path": "04-4-Cross-Stitch-Pattern-Maker-Legacy.ipynb", "parameters": { "BATCH_MODE": "true" }, - "start_time": "2026-07-27T16:44:35.181646", + "start_time": "2026-09-05T11:46:49.471031", "version": "2.6.0" - }, - "polyglot_notebook": { - "kernelInfo": { - "defaultKernelName": "csharp", - "items": [ - { - "aliases": [], - "name": "csharp" - } - ] - } - }, - "tags": [ - "NEEDS_INFRA" - ] + } }, "nbformat": 4, "nbformat_minor": 5 diff --git a/MyIA.AI.Notebooks/GenAI/Texte/10_LocalLlama.ipynb b/MyIA.AI.Notebooks/GenAI/Texte/10_LocalLlama.ipynb index cfae59aae9..3fc4c8ff02 100644 --- a/MyIA.AI.Notebooks/GenAI/Texte/10_LocalLlama.ipynb +++ b/MyIA.AI.Notebooks/GenAI/Texte/10_LocalLlama.ipynb @@ -426,11 +426,11 @@ "Et si l’on souhaite tester plusieurs endpoints (ex. mini, medium, large), on ajoute un suffixe `_2`, `_3`... :\n", "\n", "```\n", - "OPENAI_ENDPOINT_NAME_2=local-mini\n", - "OPENAI_BASE_URL_2=https://api.mini.yourdomain.com/v1\n", - "OPENAI_API_KEY_2=sk-MINI-SECRET-KEY\n", - "OPENAI_CHAT_MODEL_ID_2=unsloth/DeepSeek-R1-Distill-Llama-8B-bnb-4bit\n", - "\n", + "# NB: l'ancien endpoint `local-mini` (Oobabooga api.mini.text-generation-webui.myia.io) n'est plus joignable -- OpenRouter est le fallback valide pour cette session (cf #14593 NAMING concern #3).\n", + "OPENAI_ENDPOINT_NAME_2=OpenRouter (local-llama)\n", + "OPENAI_BASE_URL_2=https://openrouter.ai/api/v1\n", + "OPENAI_API_KEY_2=\n", + "OPENAI_CHAT_MODEL_ID_2=meta-llama/llama-3.1-8b-instruct\n", "OPENAI_ENDPOINT_NAME_3=medium\n", "OPENAI_BASE_URL_3=https://api.medium.text-generation-webui.myia.io/v1\n", "OPENAI_API_KEY_3=sk-MEDIUM-SECRET-KEY\n",