<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>AI Notebooks Archives - OVHcloud Blog</title>
	<atom:link href="https://blog.ovhcloud.com/tag/ai-notebooks/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.ovhcloud.com/tag/ai-notebooks/</link>
	<description>Innovation for Freedom</description>
	<lastBuildDate>Tue, 15 Apr 2025 07:52:47 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://blog.ovhcloud.com/wp-content/uploads/2019/07/cropped-cropped-nouveau-logo-ovh-rebranding-32x32.gif</url>
	<title>AI Notebooks Archives - OVHcloud Blog</title>
	<link>https://blog.ovhcloud.com/tag/ai-notebooks/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Reference Architecture: set up MLflow Remote Tracking Server on OVHcloud</title>
		<link>https://blog.ovhcloud.com/mlflow-remote-tracking-server-ovhcloud-databases-object-storage-ai-solutions/</link>
		
		<dc:creator><![CDATA[Eléa Petton]]></dc:creator>
		<pubDate>Tue, 15 Apr 2025 07:52:46 +0000</pubDate>
				<category><![CDATA[OVHcloud Engineering]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AI Notebooks]]></category>
		<category><![CDATA[AI Training]]></category>
		<category><![CDATA[Machine learning]]></category>
		<category><![CDATA[Managed Database]]></category>
		<category><![CDATA[MLflow]]></category>
		<category><![CDATA[Object Storage]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[OVHcloud]]></category>
		<category><![CDATA[Public Cloud]]></category>
		<guid isPermaLink="false">https://blog.ovhcloud.com/?p=28564</guid>

					<description><![CDATA[Travel through the Data &#38; AI universe of OVHcloud with the MLflow integration. As Artificial Intelligence (AI) continues to grow in importance, Data Scientists and Machine Learning Engineers need a robust and scalable platform to manage the entire Machine Learning (ML) lifecycle. MLflow, an open-source platform, provides a comprehensive framework for managing ML experiments, models, [&#8230;]<img src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fmlflow-remote-tracking-server-ovhcloud-databases-object-storage-ai-solutions%2F&amp;action_name=Reference%20Architecture%3A%20set%20up%20MLflow%20Remote%20Tracking%20Server%20on%20OVHcloud&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>Travel through the Data &amp; AI universe of OVHcloud with the <em>MLflow</em> integration.</em></p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://blog.ovhcloud.com/wp-content/uploads/2025/04/mlflow_ref_archi.svg" alt="" class="wp-image-28689"/><figcaption class="wp-element-caption"><em>Mlflow Remote Tracking Server on OVHcloud</em></figcaption></figure>



<p class="wp-block-paragraph">As <strong>Artificial Intelligence</strong> (AI) continues to grow in importance, <em>Data Scientists</em> and <em>Machine Learning Engineers</em> need a robust and scalable platform to manage the entire Machine Learning (ML) lifecycle. <br><a href="https://mlflow.org/docs/latest/introduction/index.html" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">MLflow</a>, an open-source platform, provides a comprehensive framework for managing ML experiments, models, and deployments. </p>



<p class="wp-block-paragraph"><strong>Mlflow</strong> offers many benefits and provides a complete framework for ML lifecycle management with features such as:</p>



<ul class="wp-block-list">
<li>Experiment tracking and model management</li>



<li>Reproducibility and collaboration</li>



<li>Scalability, flexibility, and integration</li>



<li>Automated ML and model serving capabilities</li>



<li>Improved model accuracy, faster time-to-market, and reduced costs.</li>
</ul>



<p class="wp-block-paragraph">In this reference architecture, you will explore how to leverage remote experience tracking with the <strong>MLflow Tracking Server</strong> on the <a href="https://www.ovhcloud.com/fr/public-cloud/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">OVHcloud Public Cloud</a> infrastructure.<br>In fact, you will be able to build a scalable and efficient ML platform, streamlining your ML workflow and accelerating model development using <strong>OVHcloud AI Notebooks</strong>, <strong>AI Training</strong>, <strong>Managed Databases (PostgreSQL)</strong>, and <strong>Object Storage</strong>.</p>



<p class="wp-block-paragraph"><strong>The result?</strong> A fully remote, <strong>production-ready ML experiment tracking pipeline</strong>, powered by OVHcloud&#8217;s Data &amp; Machine Learning Services (e.g. AI Notebooks and AI Training).</p>



<h2 class="wp-block-heading">Overview of the MLflow server architecture</h2>



<p class="wp-block-paragraph">Here is how will be configured MLflow:</p>



<ul class="wp-block-list">
<li><strong>Development and training environment:</strong> create and train model with <strong>AI Notebooks</strong></li>



<li><strong>Remote Tracking Server</strong>: host in an <strong>AI Training</strong> job (Container as a Service)</li>



<li><strong>Backend Store</strong>: benefit from a managed <strong>PostgreSQL</strong> database (DBaaS).</li>



<li><strong>Artifact Store</strong>: use OVHcloud <strong>Object Storage</strong> (S3-compatible).</li>
</ul>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://blog.ovhcloud.com/wp-content/uploads/2025/04/mlflow_overview.svg" alt="" class="wp-image-28688"/><figcaption class="wp-element-caption"><em>MLflow remote server deployment steps</em></figcaption></figure>



<p class="wp-block-paragraph">In the following tutorial, all services are deployed within the <strong>OVHcloud Public Cloud</strong>.</p>



<h2 class="wp-block-heading">Prerequisites</h2>



<p class="wp-block-paragraph">Before you begin, ensure you have:</p>



<ul class="wp-block-list">
<li>An <strong>OVHcloud Public Cloud</strong> account</li>



<li>An <strong>OpenStack user</strong> with the following roles:
<ul class="wp-block-list">
<li>Administrator</li>



<li>AI Training Operator</li>



<li>Object Storage Operator</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph"><strong>🚀 Having all the ingredients for our recipe, it’s time to set up your MLflow remote tracking server!</strong></p>



<h2 class="wp-block-heading">Architecture guide: MLflow remote tracking server</h2>



<p class="wp-block-paragraph">Let’s go for the set up and deployment of your custom MLflow tracking tool!</p>



<p class="wp-block-paragraph">⚙️<em> Also consider that all of the following steps can be automated using OVHcloud APIs!</em></p>



<h4 class="wp-block-heading">Step 1 – Install <code>ovhai</code> CLI</h4>



<p class="wp-block-paragraph">Firstly, start by setting up your CLI environment.</p>



<pre class="wp-block-code"><code class="">curl https://cli.gra.ai.cloud.ovh.net/install.sh | bash</code></pre>



<p class="wp-block-paragraph">Secondly, login using your <strong>OpenStack credentials</strong>.</p>



<pre class="wp-block-code"><code class="">ovhai login -u &lt;openstack-username&gt; -p &lt;openstack-password&gt;</code></pre>



<p class="wp-block-paragraph">Now, it&#8217;s time to create your bucket inside OVHcloud Object Storage!</p>



<h4 class="wp-block-heading">Step 2 – Provision Object Storage (Artifact Store)</h4>



<ol class="wp-block-list">
<li>Go to <strong>Public Cloud &gt; Storage &gt; Object Storage</strong> in the OVHcloud Control Panel.</li>



<li>Create a <strong>datastore</strong> and a new <strong>S3 bucket</strong> (e.g., <code>mlflow-s3-bucket</code>).</li>



<li>Register the datastore with the <code>ovhai</code> CLI:</li>
</ol>



<pre class="wp-block-code"><code class="">ovhai datastore add s3 &lt;ALIAS&gt; https://s3.gra.io.cloud.ovh.net/ gra &lt;my-access-key&gt; &lt;my-secret-key&gt; --store-credentials-locally</code></pre>



<h4 class="wp-block-heading">Step 3 – Create PostgreSQL Managed DB (Backend Store)</h4>



<p class="wp-block-paragraph">1. Navigate to <strong>Databases &amp; Analytics &gt; Databases</strong></p>



<p class="wp-block-paragraph"><strong>2. Create a new <em>PostgreSQL</em> instance with <em>Essential plan</em></strong></p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="627" src="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-13-1024x627.png" alt="" class="wp-image-28580" srcset="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-13-1024x627.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-13-300x184.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-13-768x470.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-13-1536x941.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-13-2048x1254.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><strong>3. Select <em>Location</em> and <em>Node type</em></strong></p>



<figure class="wp-block-image aligncenter size-large"><img decoding="async" width="1024" height="661" src="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-14-1024x661.png" alt="" class="wp-image-28581" srcset="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-14-1024x661.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-14-300x194.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-14-768x495.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-14-1536x991.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-14-2048x1321.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph"><strong>4. Reset the user password</strong></p>



<figure class="wp-block-image size-large"><img decoding="async" width="2384" height="1340" src="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-15-edited.png" alt="" class="wp-image-28590" srcset="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-15-edited.png 2384w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-15-edited-300x169.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-15-edited-1024x576.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-15-edited-768x432.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-15-edited-1536x863.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-15-edited-2048x1151.png 2048w" sizes="(max-width: 2384px) 100vw, 2384px" /></figure>



<p class="wp-block-paragraph"><strong>5. Take note of te following parameters</strong></p>



<p class="wp-block-paragraph">Go to your database dashboard:</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="640" src="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-16-1024x640.png" alt="" class="wp-image-28583" srcset="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-16-1024x640.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-16-300x188.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-16-768x480.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-16-1536x960.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-16-2048x1280.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Then, copy the <strong>connexion information</strong>:</p>



<pre class="wp-block-code"><code class="">&lt;db_hostname&gt;
&lt;db_username&gt;
&lt;db_password&gt;
&lt;db_name&gt;
&lt;db_port&gt;
&lt;ssl_mode&gt;</code></pre>



<p class="wp-block-paragraph">Your <strong>Backend Store</strong> is now ready to use!</p>



<h4 class="wp-block-heading">Step 4 -Build you custom MLflow Docker image and </h4>



<p class="wp-block-paragraph">1. Develop MLflow launching script</p>



<p class="wp-block-paragraph">Firstly, you have to write a script in bash to launch the server: <strong><em>mlflow_server.sh</em></strong></p>



<pre class="wp-block-code"><code class="">echo "The MLflow server is starting..."

mlflow server \
  --backend-store-uri postgresql://${POSTGRE_USER}:${POSTGRE_PASSWORD}@${PG_HOST}:${PG_PORT}/${PG_DB}?sslmode=${SSL_MODE} \
  --default-artifact-root ${S3_BUCKET_NAME}/ \
  --host 0.0.0.0 \
  --port 5000</code></pre>



<p class="wp-block-paragraph"><strong>2. Create Dockerfile</strong></p>



<p class="wp-block-paragraph">Install the required Python dependency and give the rights on the<strong> /mlruns</strong> path to the OVHcloud user.</p>



<pre class="wp-block-code"><code class="">FROM ghcr.io/mlflow/mlflow:latest

# Install Python dependencies
RUN pip install psycopg2-binary

COPY mlflow_server.sh .

# Change the ownership of `mlruns` directory to the OVHcloud user (42420:42420)
RUN mkdir -p /mlruns
RUN chown -R 42420:42420 /mlruns

# Start MLflow server inside container
CMD ["bash", "mlflow_server.sh"]</code></pre>



<p class="wp-block-paragraph"><strong>3. Build your custom MLflow docker image</strong></p>



<p class="wp-block-paragraph">Build the docker image using the previous Dockerfile.</p>



<pre class="wp-block-code"><code class="">docker build . -t mlflow-server-ai-training:latest</code></pre>



<p class="wp-block-paragraph"><strong>4. Tag and push the docker image to your registry</strong></p>



<p class="wp-block-paragraph">Finally, you can push the Docker image to your registry.</p>



<pre class="wp-block-code"><code class="">docker tag mlflow-server-ai-training:latest &lt;your-registry-address&gt;/mlflow-server-ai-training:latest</code></pre>



<pre class="wp-block-code"><code class="">docker push &lt;your-registry-address&gt;/mlflow-server-ai-training:latest</code></pre>



<p class="wp-block-paragraph">Congrats! You can now use the Docker image to launch MLflow server.</p>



<h4 class="wp-block-heading">Step 5 &#8211; Start MLflow Tracking Server inside container</h4>



<p class="wp-block-paragraph">You can use AI Training to start MLflow server inside a job.</p>



<p class="wp-block-paragraph"><strong>1. Using <code>ovhai</code> CLI, run the following command inside terminal</strong></p>



<pre class="wp-block-code"><code class="">ovhai job run --name mlflow-server \
              --default-http-port 5000 \
              --cpu 4 \
              -v mlflow-s3-bucket@DEMO/:/artifacts:RW:cache \
              -e POSTGRE_USER=avnadmin \
              -e POSTGRE_PASSWORD=&lt;db_password&gt; \
              -e S3_ENDPOINT=https://s3.gra.io.cloud.ovh.net/ \
              -e S3_BUCKET_NAME=mlflow-s3-bucket \
              -e PG_HOST=&lt;db_hostname&gt; \
              -e PG_DB=defaultdb \
              -e PG_PORT=20184 \
              -e SSL_MODE=require \
              &lt;your_registry_address&gt;/mlflow-server-ai-training:latest</code></pre>



<p class="wp-block-paragraph"><em>Full command explained:</em></p>



<ul class="wp-block-list">
<li><code>ovhai job run</code></li>
</ul>



<p class="wp-block-paragraph">This is the core command to <strong>run a job</strong> using the <strong>OVHcloud AI Training</strong> platform.</p>



<ul class="wp-block-list">
<li><code>--name mlflow-server</code></li>
</ul>



<p class="wp-block-paragraph">Sets a <strong>custom name</strong> for the job. For example, <code>mlflow-server</code>.</p>



<ul class="wp-block-list">
<li><code>--default-http-port 5000</code></li>
</ul>



<p class="wp-block-paragraph">Exposes <strong>port 5000</strong> as the default HTTP endpoint. MLflow’s web UI typically runs on port 5000, so this ensures the UI is accessible once the job is running.</p>



<ul class="wp-block-list">
<li><code>--cpu </code>4</li>
</ul>



<p class="wp-block-paragraph">Allocates <strong>4 CPUs</strong> for the job. You can adjust this based on how heavy your MLflow workload is.</p>



<ul class="wp-block-list">
<li><code>-v mlflow-s3-bucket@DEMO/:/artifacts:RW:cache</code></li>
</ul>



<p class="wp-block-paragraph">This mounts your <strong>OVHcloud Object Storage volume</strong> into the job’s file system:<br>&#8211; <code>mlflow-s3-bucket@DEMO/</code>: refers to your <strong>S3 bucket volume</strong> from the OVHcloud Object Storage<br>&#8211; <code>:/artifacts</code>: mounts the volume into the container under <code>/artifacts</code><br>&#8211; <code>RW</code>: enables <strong>Read/Write</strong> permissions<br>&#8211; <code>cache</code>: enables <strong>volume caching</strong>, improving performance for frequent reads/writes</p>



<ul class="wp-block-list">
<li><code>-e POSTGRE_USER=avnadmin</code></li>



<li><code>-e POSTGRE_PASSWORD=&lt;db_password&gt;</code></li>



<li><code>-e PG_HOST=&lt;db_hostname&gt;</code></li>



<li><code>-e PG_DB=defaultdb</code></li>



<li><code>-e PG_PORT=20184</code></li>



<li><code>-e SSL_MODE=require</code></li>
</ul>



<p class="wp-block-paragraph">These are <strong>environment variables</strong> for connecting to the <strong>PostgreSQL </strong>backend store:<br>&#8211; <code>avnadmin</code>: the default admin user for OVHcloud’s managed PostgreSQL<br>&#8211; <code>POSTGRE_PASSWORD</code>: must be replaced with your actual database password<br>&#8211; <code>PG_HOST</code>: the hostname of your managed PostgreSQL instance<br>&#8211; <code>PG_DB</code>: the name of the database to use (default: <code>defaultdb</code>)<br>&#8211; <code>PG_PORT</code>: the port your PostgreSQL server is listening on<br>&#8211; <code>SSL_MODE</code>: enforce SSL connection to secure DB traffic</p>



<ul class="wp-block-list">
<li><code>-e S3_ENDPOINT=https://s3.gra.io.cloud.ovh.net/</code></li>
</ul>



<p class="wp-block-paragraph">Tells MLflow where the <strong>S3-compatible endpoint</strong> is hosted. This is specific to OVHcloud&#8217;s GRA (Gravelines) region Object Storage.</p>



<ul class="wp-block-list">
<li><code>-e S3_BUCKET_NAME=mlflow-s3-bucket</code></li>
</ul>



<p class="wp-block-paragraph">Sets the <strong>name of the S3 bucket</strong> where MLflow should store artifacts (models, metrics, etc.).</p>



<ul class="wp-block-list">
<li><code>&lt;your_registry_address&gt;/mlflow-server-ai-training:latest</code></li>
</ul>



<p class="wp-block-paragraph">This is the<strong> custom MLflow Docker image</strong> you are running inside the job.</p>



<p class="wp-block-paragraph"><strong>2. Check if your AI Training job is RUNNING</strong></p>



<p class="wp-block-paragraph">Replace the <code>&lt;job_id&gt;</code> by yours.</p>



<pre class="wp-block-code"><code class="">ovhai job get &lt;job_id&gt;</code></pre>



<p class="wp-block-paragraph">You should obtain:</p>



<p class="wp-block-paragraph"><code>History:<br>    DATE                  STATE<br>    04-04-25 09:58:00     QUEUED<br>    04-04-25 09:58:01     INITIALIZING<br>    04-04-25 09:58:07     PENDING<br>    04-04-25 09:58:10     <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color">RUNNING</mark></strong><br>  Info:<br>    Message:   Job is running</code></p>



<p class="wp-block-paragraph"><strong>3. Recover the IP and external IP of your AI Training job</strong></p>



<p class="wp-block-paragraph">Using, your <code>&lt;job_id&gt;</code>, you can retrieve your AI Training <strong>job IP</strong>.</p>



<pre class="wp-block-code"><code class="">ovhai job get &lt;job_id&gt; -o json | jq '.status.ip' -r</code></pre>



<p class="wp-block-paragraph">For example, you can obtain something like that: <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color">10.42.80.176</mark></strong></p>



<p class="wp-block-paragraph">You also need the External IP:</p>



<pre class="wp-block-code"><code class="">ovhai job get &lt;job_id&gt; -o json | jq '.status.externalIp' -r</code></pre>



<p class="wp-block-paragraph">Returning the IP address you will have to whitelist to be able to connect to your database (e.g. <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color"><strong>51.210.38.188</strong></mark>)</p>



<h4 class="wp-block-heading">Step 6 – Whitelist AI Training job IP in PostgreSQL DB</h4>



<p class="wp-block-paragraph">From <strong>Databases &amp; Analytics &gt; Databases</strong>, edit your DB configuration to <strong>allow access from the job Extranal IP</strong>.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="475" src="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-19-1024x475.png" alt="" class="wp-image-28593" srcset="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-19-1024x475.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-19-300x139.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-19-768x356.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-19-1536x712.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-19-2048x950.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Then, you can see that the job External IP is now white listed.</p>



<p class="wp-block-paragraph">Well done! Your MLflow server and the backend store are now connected.</p>



<h4 class="wp-block-heading">Step 7 –  Create an AI Notebook</h4>



<p class="wp-block-paragraph">It&#8217;s time to train and track your Machine Learning models using MLflow!</p>



<p class="wp-block-paragraph">To do so, use the OVHcloud <code>ovhai</code> CLI and start a new AI Notebook with GPU.</p>



<pre class="wp-block-code"><code class="">ovhai notebook run conda jupyterlab \
  --name mlflow-notebook \
  --framework-version conda-py311-cudaDevel11.8 \
  --gpu 1</code></pre>



<p class="wp-block-paragraph"><em>Full command explained:</em></p>



<ul class="wp-block-list">
<li><code>ovhai noteb</code>ook<code> run</code></li>
</ul>



<p class="wp-block-paragraph">This is the core command to <strong>run a notebook</strong> using the <strong>OVHcloud AI Notebooks</strong> platform.</p>



<ul class="wp-block-list">
<li><code>--name mlflow-notebook</code></li>
</ul>



<p class="wp-block-paragraph">Sets a <strong>custom name</strong> for the notebook. In this case, you can name it <code>mlflow-notebook</code>.</p>



<ul class="wp-block-list">
<li><code>--framework-version conda-py311-cudaDevel11.8</code></li>
</ul>



<p class="wp-block-paragraph">Define the framework and version you want to use in your notebook. Here, you are using Python 3.11 with Conda framework and CUDA compatibility.</p>



<ul class="wp-block-list">
<li><code>--gpu 1</code></li>
</ul>



<p class="wp-block-paragraph">Allocates <strong>1 GPU</strong> for the job, by default a <strong>Tesla V100S</strong> from NVIDIA (<code>ai1-1-gpu</code>). You can select the flavor you want from the OVHcloud GPU range.</p>



<p class="wp-block-paragraph">Then, check if your AI Notebook is RUNNING.</p>



<pre class="wp-block-code"><code class="">ovhai notebook get &lt;notebook_id&gt;</code></pre>



<p class="wp-block-paragraph">Once your notebook is in RUNNING status, you should be able to access it using its URL:</p>



<p class="wp-block-paragraph"><code>State:          <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color">RUNNING</mark></strong><br>Duration:       1411412   <br>Url:            <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color">https://&lt;notebook_id&gt;.notebook.gra.ai.cloud.ovh.net</mark></strong><br>Grpc Address:   &lt;notebook_id&gt;.nb-grpc.gra.ai.cloud.ovh.net:443<br>Info Url:       https://ui.gra.ai.cloud.ovh.net/notebook/&lt;notebook_id&gt;</code></p>



<p class="wp-block-paragraph">You can start your AI model development inside notebook.</p>



<h4 class="wp-block-heading">Step 8 – Model training inside Jupyter notebook</h4>



<p class="wp-block-paragraph">To begin with, set up your notebook environment.</p>



<p class="wp-block-paragraph"><strong>1. Create the <code>requirements.txt</code> file</strong></p>



<pre class="wp-block-code"><code class="">numpy==2.2.3
scipy==1.15.2
mlflow==2.20.3
sklearn==1.6.1</code></pre>



<p class="wp-block-paragraph"><strong>2. Install dependencies</strong></p>



<p class="wp-block-paragraph">From a notebook cell, launch the following command.</p>



<pre class="wp-block-code"><code class="">!pip3 install -r requirements.txt</code></pre>



<p class="wp-block-paragraph">Perfect! You can start coding&#8230;</p>



<p class="wp-block-paragraph"><strong> 3. Import Python librairies</strong></p>



<p class="wp-block-paragraph">Here, you have to import os, mlflow and scikit-learn.</p>



<pre class="wp-block-code"><code class=""># import dependencies
import os
import mlflow
import sklearn
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_diabetes
from sklearn.ensemble import RandomForestRegressor</code></pre>



<p class="wp-block-paragraph">In another notebook cell, set the MLflow tracking URI. Note that you have to replace <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color">10.42.80.176</mark></strong> by your own <strong>job IP</strong>.</p>



<pre class="wp-block-code"><code class="">mlflow.set_tracking_uri("http://<strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color">10.42.80.176</mark></strong>:5000")</code></pre>



<p class="wp-block-paragraph">Then start training your model!</p>



<pre class="wp-block-code"><code class="">mlflow.autolog()

db = load_diabetes()
X_train, X_test, y_train, y_test = train_test_split(db.data, db.target)

# Create and train models.
rf = RandomForestRegressor(n_estimators=100, max_depth=6, max_features=3)
rf.fit(X_train, y_train)

# Use the model to make predictions on the test dataset.
predictions = rf.predict(X_test)</code></pre>



<p class="wp-block-paragraph"><strong>Output:</strong></p>



<p class="wp-block-paragraph"><code>🏃 View run dashing-foal-850 at: http://<strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color">10.42.80.176</mark></strong>:5000/#/experiments/0/runs/e7dad7c073634ec28675c0defce2b9ec </code><br><code>🧪 View experiment at: http://<strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color">10.42.80.176</mark></strong>:5000/#/experiments/0</code></p>



<p class="wp-block-paragraph">Congrats! You can now track your model training from<strong> MLflow remote server</strong>&#8230;</p>



<h4 class="wp-block-heading">Step 9 – Track and compare models from MLflow remote server</h4>



<p class="wp-block-paragraph">Finally, access to MLflow dashboard using the job URL: <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-ast-global-color-0-color"><code>https://&lt;job_id&gt;.job.gra.ai.cloud.ovh.net</code></mark></strong></p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="578" src="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-23-1024x578.png" alt="" class="wp-image-28598" srcset="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-23-1024x578.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-23-300x169.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-23-768x433.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-23-1536x867.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-23-2048x1155.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Then, you can check your model trainings and evaluations:</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="577" src="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-24-1024x577.png" alt="" class="wp-image-28599" srcset="https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-24-1024x577.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-24-300x169.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-24-768x433.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-24-1536x866.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2025/04/image-24-2048x1154.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">What a success! You can finally use your MLflow to evaluate, compare and archive your various trainings.</p>



<h4 class="wp-block-heading">Step 10 &#8211; Monitor everything remotely</h4>



<p class="wp-block-paragraph">You now have a complete Machine Learning pipeline with remote experiment tracking. Access:</p>



<ul class="wp-block-list">
<li><strong>Metrics, Parameters, and Tags</strong> → PostgreSQL</li>



<li><strong>Artifacts (Models, Files)</strong> → S3 bucket</li>
</ul>



<p class="wp-block-paragraph">This setup is reusable, automatable, and production-ready!</p>



<h2 class="wp-block-heading">What’s next?</h2>



<ul class="wp-block-list">
<li>Automate deployment with <strong><a href="https://eu.api.ovh.com/" data-wpel-link="exclude">OVHcloud APIs</a></strong></li>



<li>Run different training sessions in parallel and compare them with your <strong>remote MLflow tracking server</strong></li>



<li>Use <strong><a href="https://www.ovhcloud.com/fr/public-cloud/ai-deploy/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">AI Deploy</a></strong> to serve your trained models</li>
</ul>
<img loading="lazy" decoding="async" src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fmlflow-remote-tracking-server-ovhcloud-databases-object-storage-ai-solutions%2F&amp;action_name=Reference%20Architecture%3A%20set%20up%20MLflow%20Remote%20Tracking%20Server%20on%20OVHcloud&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Create your solution for Sign Language recognition with OVHcloud AI tools</title>
		<link>https://blog.ovhcloud.com/create-your-solution-for-sign-language-recognition-with-ovhcloud-ai-tools/</link>
		
		<dc:creator><![CDATA[Eléa Petton]]></dc:creator>
		<pubDate>Fri, 01 Sep 2023 09:27:49 +0000</pubDate>
				<category><![CDATA[OVHcloud Engineering]]></category>
		<category><![CDATA[AI Deploy]]></category>
		<category><![CDATA[AI Notebooks]]></category>
		<category><![CDATA[AI Training]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Machine learning]]></category>
		<guid isPermaLink="false">https://blog.ovhcloud.com/?p=25709</guid>

					<description><![CDATA[A guide to build a solution for sign language interpretation based on a Computer Vision algorithm: YOLOv7. Introduction In the field of Artificial Intelligence, we often talk about Computer Vision and Object Detection, but what role do these AI techniques play in the vast field of healthcare? We&#8217;ll see that data plays a key role [&#8230;]<img src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fcreate-your-solution-for-sign-language-recognition-with-ovhcloud-ai-tools%2F&amp;action_name=Create%20your%20solution%20for%20Sign%20Language%20recognition%20with%20OVHcloud%20AI%20tools&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>A guide to build a solution for sign language interpretation based on a <strong>Computer Vision</strong> algorithm: <a href="https://github.com/WongKinYiu/yolov7" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">YOLOv7</a>.</em></p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="617" src="https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.52-1024x617.png" alt="" class="wp-image-25717" srcset="https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.52-1024x617.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.52-300x181.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.52-768x463.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.52-1536x925.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.52.png 1738w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption"><em>Sign Language recognition with OVHcloud AI tools</em></figcaption></figure>



<h2 class="wp-block-heading">Introduction</h2>



<p class="wp-block-paragraph">In the field of Artificial Intelligence, we often talk about <strong>Computer Vision</strong> and <strong>Object Detection</strong>, but what role do these AI techniques play in the vast field of healthcare? We&#8217;ll see that data plays a key role in AI applications for the medical-social sector. </p>



<p class="wp-block-paragraph"><strong>Have you ever wondered if AI could be the solution to understand sign language?</strong></p>



<p class="wp-block-paragraph">Through this article, you will see that it is possible to use an AI model to detect signed letters. How? Thanks to the power of <strong>Computer Vision</strong> and <strong>Transfer Learning</strong>!</p>



<p class="wp-block-paragraph"><strong>The article is organized as follows:</strong></p>



<ul class="wp-block-list">
<li>Objectives</li>



<li>American Sign Language Dataset</li>



<li>Fine-Tune YOLOv7 model for Sign Language detection</li>



<li>Deploy custom YOLOv7 model for real time detection</li>
</ul>



<p class="wp-block-paragraph"><em>All the code for this blogpost is available in our dedicated <a href="https://github.com/ovh/ai-training-examples" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">G</a><a href="https://github.com/ovh/ai-training-examples/blob/main/notebooks/computer-vision/object-detection/miniconda/yolov7/notebook_object_detection_yolov7_asl.ipynb" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">itHub repository</a>. You can <a href="https://help.ovhcloud.com/csm/en-gb-public-cloud-ai-notebooks-yolov7-sign-language?id=kb_article_view&amp;sysparm_article=KB0057517" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">Fine-Tune YOLOv7</a> to detect signs with <strong>AI Notebooks</strong> tool and <a href="https://help.ovhcloud.com/csm/en-gb-public-cloud-ai-deploy-streamlit-yolov7-sign-language?id=kb_article_view&amp;sysparm_article=KB0057491" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">deploy the custom model</a> for real-time detection with <strong>AI Deploy</strong>.</em></p>



<h2 class="wp-block-heading">Objectives</h2>



<p class="wp-block-paragraph">The purpose of this article is to show how it is possible to deploy a solution for <strong>Sign Language recognition</strong> thanks to AI. </p>



<p class="wp-block-paragraph">An <strong>Object Detection</strong> algorithm will be used to detect the various signs and categorize them. Although closely related to image classification, <strong>Object Detection </strong>performs <strong>Image Classification</strong> on a more precise scale.</p>



<p class="wp-block-paragraph">In this article, you will learn how to <strong><a href="https://github.com/ovh/ai-training-examples/blob/main/notebooks/computer-vision/object-detection/miniconda/yolov7/notebook_object_detection_yolov7_asl.ipynb" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">Fine-Tune YOLOv7</a></strong> model for <strong>Sign Language</strong> detection.</p>



<p class="wp-block-paragraph">Once the model has been trained, what do you think of deploying a web app? <strong>Streamlit</strong> is the answer to your needs! At the end, AI will enable you to understand Sign Language, with <strong>real-time detection</strong> and written transcription.</p>



<h2 class="wp-block-heading">American Sign Language Dataset</h2>



<p class="wp-block-paragraph">First of all, let&#8217;s talk data!</p>



<p class="wp-block-paragraph"><a href="https://public.roboflow.com/object-detection/american-sign-language-letters/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">American Sign Language Letters Dataset v1</a> is a public set of alphabet images and their labels created by <strong>David Lee</strong>.</p>



<p class="wp-block-paragraph">This dataset is composed of <strong>1728 images</strong> and <strong>26 classes</strong> with the alphabet letters from A to Z.</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-7387b849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:100%">
<figure class="wp-block-image aligncenter size-full is-resized"><img loading="lazy" decoding="async" src="https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.00-1.png" alt="" class="wp-image-25725" style="width:377px;height:390px" width="377" height="390" srcset="https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.00-1.png 935w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.00-1-290x300.png 290w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.00-1-768x794.png 768w" sizes="auto, (max-width: 377px) 100vw, 377px" /><figcaption class="wp-element-caption"><em>ASL dataset</em></figcaption></figure>
</div>
</div>



<p class="wp-block-paragraph">This dataset is composed of <strong>images</strong> and their corresponding <strong>labels</strong>, which are in <strong>txt</strong> format and give information about the location of the object thanks to the <em>x</em>, <em>y</em> coordinates as well as the <em>height</em> and <em>width</em> of the bounding box.</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img loading="lazy" decoding="async" src="https://blog.ovhcloud.com/wp-content/uploads/2022/01/mug_annotation-1024x635.png" alt="" class="wp-image-21645" style="width:1024px;height:635px" width="1024" height="635" srcset="https://blog.ovhcloud.com/wp-content/uploads/2022/01/mug_annotation-1024x635.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2022/01/mug_annotation-300x186.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2022/01/mug_annotation-768x477.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2022/01/mug_annotation-1536x953.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2022/01/mug_annotation.png 1713w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption"><em>Label components of the ASL dataset for YOLOv7 usage</em></figcaption></figure>



<p class="wp-block-paragraph">This data format is ideal for training a <strong>YOLO</strong> type Object Detection model.</p>



<h2 class="wp-block-heading">Fine-Tune YOLOv7 model for Sign Language recognition</h2>



<p class="wp-block-paragraph">How can the model YOLOv7 be trained to recognize American Sign Language letters? </p>



<h6 class="wp-block-heading"><strong>Object Detection with YOLOv7 </strong></h6>



<p class="wp-block-paragraph"><strong>YOLOv7</strong> is part of the &#8220;YOLO family&#8221; algorithms, which actually means &#8220;<em>You Only Look Once</em>.&#8221; In fact, unlike many detection algorithms, YOLO is a neural network that evaluates the position and class of identified objects from a <strong>single end-to-end network</strong> that detects classes using a fully connected layer.</p>



<figure class="wp-block-image aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-14.02.47-1024x991.png" alt="" class="wp-image-25722" style="width:533px;height:515px" width="533" height="515" srcset="https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-14.02.47-1024x991.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-14.02.47-300x290.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-14.02.47-768x743.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-14.02.47.png 1059w" sizes="auto, (max-width: 533px) 100vw, 533px" /><figcaption class="wp-element-caption"><em>Object Detection</em></figcaption></figure>



<p class="wp-block-paragraph">Therefore, YOLO models pass only once on each image to detect the objects. This Object Detection model is particularly known for its <strong>speed</strong> and <strong>accuracy</strong> and allows <strong>real-time recognition</strong>.</p>



<p class="wp-block-paragraph">But how can the model YOLOv7 be trained to recognize American Sign Language letters? Follow the next steps and let the magic work!</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="266" src="https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.27-1024x266.png" alt="" class="wp-image-25719" srcset="https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.27-1024x266.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.27-300x78.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.27-768x200.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.27-1536x400.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-11.23.27.png 1841w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption"><em>Fine-Tuning of YOLOv7</em></figcaption></figure>



<p class="wp-block-paragraph"><em>The full notebook is available on the following <a href="https://github.com/ovh/ai-training-examples/blob/main/notebooks/computer-vision/object-detection/miniconda/yolov7/notebook_object_detection_yolov7_asl.ipynb" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">GitHub repository</a>.</em></p>



<h4 class="wp-block-heading">Import dependencies</h4>



<p class="wp-block-paragraph">Firstly, import the dependencies you need.</p>



<pre class="wp-block-code"><code class="">import torch
import os
import yaml
import torchvision
from IPython.display import Image, clear_output</code></pre>



<h4 class="wp-block-heading">Check GPU availability</h4>



<p class="wp-block-paragraph">Then, check the GPU availability. Indeed, the training of a model like YOLOv7 requires the use of <strong>GPU</strong>, in this case a Tesla V100S is used.</p>



<pre class="wp-block-code"><code class="">print('Setup complete. Using torch %s %s' % (torch.__version__, torch.cuda.get_device_properties(0) if torch.cuda.is_available() else 'CPU'))</code></pre>



<p class="wp-block-paragraph"><code>Setup complete. Using torch 1.12.1+cu102 _CudaDeviceProperties(name='Tesla V100S-PCIE-32GB', major=7, minor=0, total_memory=32510MB, multi_processor_count=80)</code></p>



<h4 class="wp-block-heading">Extract the dataset information</h4>



<p class="wp-block-paragraph">Next, you can access to the <code>data.yaml</code> file.</p>



<p class="wp-block-paragraph">This file contains vital information about the dataset, especially the number of classes. Here we got 26 classes with the letters from A to Z.</p>



<pre class="wp-block-code"><code class=""># go to the directory where the data.yaml file is located to extract the number of classes
%cd /workspace/data
with open("data.yaml", 'r') as stream:
    num_classes = str(yaml.safe_load(stream)['nc'])</code></pre>



<p class="wp-block-paragraph">Now, it&#8217;s time to train YOLOv7 model!</p>



<h4 class="wp-block-heading">Recover YOLOv7 weights</h4>



<p class="wp-block-paragraph">In this tutorial, you can use the&nbsp;<strong>Transfer Learning</strong>&nbsp;method by using YOLOv7 weights pre-trained on the&nbsp;<a href="https://cocodataset.org/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">COCO dataset</a>.</p>



<p class="wp-block-paragraph"><strong>How to define Transfer Learning?</strong></p>



<p class="wp-block-paragraph">For both humans and machines, learning something new takes time and practice. However, it is easier to perform out tasks similar to those already learned. As with humans, AI will be able to identify patterns from previous knowledge and apply them to new learning.</p>



<p class="wp-block-paragraph">If a model is trained on a database, there is no need to re-train the model from scratch to fit a new set of similar data.</p>



<p class="wp-block-paragraph"><strong>Main advantages of Transfer Learning:</strong></p>



<ul class="wp-block-list">
<li>saving resources</li>



<li>improving efficiency</li>



<li>model training facilitation</li>



<li>saving time</li>
</ul>



<p class="wp-block-paragraph">At this time, you can download the trained model:</p>



<pre class="wp-block-code"><code class=""># YOLOv7 path
%cd /workspace/yolov7
!wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7_training.pt</code></pre>



<p class="wp-block-paragraph"><code>Saving to: ‘yolov7_training.pt’<br>yolov7_training.pt 100%[===================&gt;] 72.12M 12.0MB/s in 5.5s</code></p>



<h4 class="wp-block-heading">Run YOLOv7 training on ASL Letters Dataset</h4>



<p class="wp-block-paragraph">You can therefore set the following parameters.</p>



<ul class="wp-block-list">
<li><em><strong>workers:</strong></em> maximum number of dataloader workers.</li>



<li><em><strong>device:</strong></em> cuda device.</li>



<li><strong><em>batch-size:</em></strong> refers to the batch size (number of training examples used in one iteration).</li>



<li><strong><em>data:</em></strong> refers to the path to the yaml file.</li>



<li><strong><em>img:</em></strong> refers to the input images size.</li>



<li><strong><em>cfg:</em></strong> define the model configuration.</li>



<li><strong><em>weights:</em></strong> initial weights path.</li>



<li><strong><em>name:</em></strong> save to project/name.</li>



<li><strong><em>hyp:</em></strong> hyperparameters path.</li>



<li><strong><em>epochs:</em></strong> refers to the number of training epochs. An epoch corresponds to one cycle through the full training dataset.</li>
</ul>



<pre class="wp-block-code"><code class=""># time the performance
%time

# train yolov7 on custom data for 100 epochs
!python /workspace/yolov7/train.py \
          --workers 8 \
          --device 0 \
          --batch-size 8 \
          --data '/workspace/data/data.yaml' \
          --img 416 416 \
          --cfg '/workspace/yolov7/cfg/training/yolov7.yaml' \
          --weights '/workspace/yolov7/yolov7_training.pt' \
          --name yolov7-asl \
          --hyp '/workspace/yolov7/data/hyp.scratch.custom.yaml' \
          --epochs 100</code></pre>



<h4 class="wp-block-heading">Display results of YOLOv7 training on ASL Letters dataset</h4>



<p class="wp-block-paragraph">Then you can display the results of the training and check the evolution of the metrics.</p>



<pre class="wp-block-code"><code class=""># display images
Image(filename='/workspace/yolov7/runs/train/yolov7-asl/results.png', width=1000)  # view results</code></pre>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="512" src="https://blog.ovhcloud.com/wp-content/uploads/2023/08/image-1024x512.png" alt="" class="wp-image-25713" srcset="https://blog.ovhcloud.com/wp-content/uploads/2023/08/image-1024x512.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/image-300x150.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/image-768x384.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/image-1536x768.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/image-2048x1024.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption"><em>YOLOv7 training overview</em></figcaption></figure>



<h4 class="wp-block-heading">Export new weights for future inference</h4>



<p class="wp-block-paragraph">Finally, you can extract the <strong>new weights</strong> coming from YOLOv7 training on ASL Alphabet dataset. The goal is to save the model weights in a bucket in the cloud for reuse in a dedicated application.</p>



<p class="wp-block-paragraph">Firstly, rename the PyTorch model it with the name you want.</p>



<pre class="wp-block-code"><code class="">%cd /workspace/yolov7/runs/train/yolov7-asl/weights/
os.rename("best.pt","yolov7.pt")</code></pre>



<p class="wp-block-paragraph"><code>/workspace/yolov7/runs/train/yolov7-asl/weights</code></p>



<p class="wp-block-paragraph">Secondly, copy it in a new folder where you can put all the weights generated during your trainings.</p>



<pre class="wp-block-code"><code class="">%cp /workspace/yolov7/runs/train/yolov7-asl/weights/yolov7.pt /workspace/asl-volov7-model/yolov7.pt</code></pre>



<p class="wp-block-paragraph"><strong>Your model is ready?</strong> It&#8217;s now time to deploy a web app to use the model and benefit from real-time detection 🎉 !</p>



<h2 class="wp-block-heading">Deploy custom YOLOv7 model for real time detection</h2>



<p class="wp-block-paragraph">Once this <strong>YOLOv7 model</strong> is trained, it can be used for inference. If you want to quickly build an app to serve your AI model, the <strong>Streamlit</strong> framework may be right for you.</p>



<h6 class="wp-block-heading"><strong>What is Streamlit?</strong></h6>



<p class="wp-block-paragraph">Now, it&#8217;s time to discuss about the framework used to create a Web App: <strong>Streamlit</strong>!</p>



<p class="wp-block-paragraph"><a href="https://streamlit.io/" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">Streamlit</a>&nbsp;allows you to transform data scripts into quickly shareable web applications using only the&nbsp;<strong>Python</strong>&nbsp;language. Moreover, this framework does not require front-end skills.</p>



<p class="wp-block-paragraph">This is a time-saver for the data scientist who wants to deploy an app around the world of data!</p>



<p class="wp-block-paragraph">To make this app accessible, you need to containerize it using&nbsp;<strong>Docker</strong>.</p>



<figure class="wp-block-image aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-14.00.50-1024x960.png" alt="" class="wp-image-25723" style="width:601px;height:564px" width="601" height="564" srcset="https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-14.00.50-1024x960.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-14.00.50-300x281.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-14.00.50-768x720.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/Capture-decran-2023-08-28-a-14.00.50.png 1098w" sizes="auto, (max-width: 601px) 100vw, 601px" /><figcaption class="wp-element-caption"><em>Streamlit web app</em></figcaption></figure>



<p class="wp-block-paragraph">By creating an app, you will enable anyone to <strong>understand Sign Language</strong>, with Real-Time detection and written transcription.</p>



<p class="wp-block-paragraph">Let&#8217;s go for the implementation!</p>



<h4 class="wp-block-heading">Create the interface with Streamlit</h4>



<p class="wp-block-paragraph">First of all, we must build the <strong>web interface</strong> to take a photo and the various functions to analyze the signs present on this image.</p>



<ul class="wp-block-list">
<li><code>load_model</code>: this function should be pushed in &#8220;cache&#8221; so that you only have to load the model once</li>
</ul>



<pre class="wp-block-code"><code class="">@st.cache
def load_model():

    custom_yolov7_model = torch.hub.load("WongKinYiu/yolov7", 'custom', '/workspace/asl-volov7-model/yolov7.pt')

    return custom_yolov7_model</code></pre>



<ul class="wp-block-list">
<li><code>get_prediction</code>: the model analyzes the image and returns the result of the prediction</li>
</ul>



<pre class="wp-block-code"><code class="">def get_prediction(img_bytes, model):

    img = Image.open(io.BytesIO(img_bytes))
    results = model(img, size=640)

    return results</code></pre>



<ul class="wp-block-list">
<li><code>analyse_image</code>: the image is processed before and after the model analysis</li>
</ul>



<pre class="wp-block-code"><code class="">def analyse_image(image, model):

    if image is not None:

        img = Image.open(image)

        bytes_data = image.getvalue()
        img_bytes = np.asarray(bytearray(bytes_data), dtype=np.uint8)
        result = get_prediction(img_bytes, model)
        result.render()

        for img in result.imgs:
            RGB_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            im_arr = cv2.imencode('.jpg', RGB_img)[1]
            st.image(im_arr.tobytes())

        result_list = list((result.pandas().xyxy[0])["name"])

    else:
        st.write("no asl letters were detected!")
        result_list = []

    return result_list</code></pre>



<ul class="wp-block-list">
<li><code>display_letters</code>: the letters are recovered and displayed to form the final word</li>
</ul>



<pre class="wp-block-code"><code class="">def display_letters(letters_list):

    word = ''.join(letters_list)
    path_file = "/workspace/word_file.txt"
    with open(path_file, "a") as f:
        f.write(word)

    return path_file</code></pre>



<p class="wp-block-paragraph"><em>To access the full code of the app, refer to this <a href="https://github.com/ovh/ai-training-examples/tree/main/apps/streamlit/sign-language-recognition-yolov7-app" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">GitHub</a><a href="https://github.com/ovh/ai-training-examples/blob/main/apps/streamlit/sign-language-recognition-yolov7-app/main.py" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer"> repository</a>.</em></p>



<h4 class="wp-block-heading">Containerize your app with Docker</h4>



<p class="wp-block-paragraph">Once the app code has been created, it&#8217;s time to containerize it!</p>



<p class="wp-block-paragraph">The containerization is based on the construction of a Docker image, and before this image is usable, several steps must be completed.</p>



<p class="wp-block-paragraph"><strong>What are the containerization steps 🐳 ?</strong></p>



<p class="wp-block-paragraph"><em>The following steps refer to this <a href="https://help.ovhcloud.com/csm/en-gb-public-cloud-ai-deploy-streamlit-yolov7-sign-language?id=kb_article_view&amp;sysparm_article=KB0057491" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">documentation</a> where you can find detailed information.</em></p>



<ul class="wp-block-list">
<li>Write the <a href="https://github.com/ovh/ai-training-examples/blob/main/apps/streamlit/sign-language-recognition-yolov7-app/requirements.txt" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">requirements.txt</a> file</li>



<li>Create the <a href="https://github.com/ovh/ai-training-examples/blob/main/apps/streamlit/sign-language-recognition-yolov7-app/Dockerfile" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">Dockerfile</a></li>



<li><a href="https://help.ovhcloud.com/csm/fr-public-cloud-ai-deploy-streamlit-yolov7-sign-language?id=kb_article_view&amp;sysparm_article=KB0057495#build-the-docker-image-from-the-dockerfile" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">Build the Docker image</a></li>



<li><a href="https://help.ovhcloud.com/csm/fr-public-cloud-ai-deploy-streamlit-yolov7-sign-language?id=kb_article_view&amp;sysparm_article=KB0057495#push-the-image-into-the-shared-registry" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">Tag and push the Docker image on a registry</a></li>
</ul>



<p class="wp-block-paragraph">Your docker image is created successfully? You are ready to launch your app 🚀 !</p>



<h4 class="wp-block-heading">Deploy your app and make it accessible</h4>



<p class="wp-block-paragraph">The following command starts a new AI Deploy app running your Streamlit web interface.</p>



<pre class="wp-block-code"><code class="">ovhai app run
       --gpu 1 \
       --default-http-port 8501 \
       --volume asl-volov7-model@GRA/:/workspace/asl-volov7-model:RO \
       &lt;shared-registry-address&gt;/yolov7-streamlit-asl-recognition:latest</code></pre>



<p class="wp-block-paragraph">In this command line, you can set up several parameters:</p>



<ul class="wp-block-list">
<li><code>resources</code>: choose between CPUs or GPUs</li>



<li><code>default HTTP port</code>: precise the Streamlit default port &#8211; 8501</li>



<li><code>data</code>: link the bucket containing your model</li>



<li><code>docker image</code>: add your docker image addess</li>
</ul>



<p class="wp-block-paragraph">When your app is up and running, you can access the following page:</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="648" height="1024" src="https://blog.ovhcloud.com/wp-content/uploads/2023/08/overview-streamlit-yolov7-asl-648x1024.png" alt="" class="wp-image-25720" srcset="https://blog.ovhcloud.com/wp-content/uploads/2023/08/overview-streamlit-yolov7-asl-648x1024.png 648w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/overview-streamlit-yolov7-asl-190x300.png 190w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/overview-streamlit-yolov7-asl-768x1214.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/overview-streamlit-yolov7-asl-972x1536.png 972w, https://blog.ovhcloud.com/wp-content/uploads/2023/08/overview-streamlit-yolov7-asl.png 988w" sizes="auto, (max-width: 648px) 100vw, 648px" /><figcaption class="wp-element-caption"><em>Resulting Streamlit app</em></figcaption></figure>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">Well done 🎉&nbsp;! You have learned how to create <strong>your own solution for Sign Language recognition</strong> with OVHcloud AI tools.</p>



<p class="wp-block-paragraph">You have been able to <strong>Fine-Tune YOLOv7 model</strong> thanks to <em>AI Notebooks</em> and <strong>deploy a Real-Time recognition app</strong> with <em>AI Deploy</em>.</p>



<h4 class="wp-block-heading" id="want-to-find-out-more">Want to find out more?</h4>



<h6 class="wp-block-heading"><strong>Notebook</strong></h6>



<p class="wp-block-paragraph">You want to access the notebook? Refer to the&nbsp;<a href="https://github.com/ovh/ai-training-examples/blob/main/notebooks/computer-vision/object-detection/miniconda/yolov7/notebook_object_detection_yolov7_asl.ipynb" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">GitHub repository</a>.</p>



<p class="wp-block-paragraph">To launch this notebook with&nbsp;<strong>AI Notebook</strong>, please refer to&nbsp;our&nbsp;<a href="https://help.ovhcloud.com/csm/en-gb-public-cloud-ai-notebooks-yolov7-sign-language?id=kb_article_view&amp;sysparm_article=KB0057517" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">documentation</a>.</p>



<h6 class="wp-block-heading"><strong>App</strong></h6>



<p class="wp-block-paragraph">You want to access to the full code to create the Streamlit app? Refer to the&nbsp;<a href="https://github.com/ovh/ai-training-examples/tree/main/apps/streamlit/sign-language-recognition-yolov7-app" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">GitHub repository</a>.<br><br>To deploy this app with&nbsp;<strong>AI Deploy</strong>, please refer to&nbsp;our&nbsp;<a href="https://help.ovhcloud.com/csm/en-gb-public-cloud-ai-deploy-streamlit-yolov7-sign-language?id=kb_article_view&amp;sysparm_article=KB0057491" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">doc</a><a href="https://docs.ovh.com/gb/en/publiccloud/ai/deploy/tuto-streamlit-eda-iris/" data-wpel-link="exclude">umentation</a>.</p>



<h2 class="wp-block-heading">References</h2>



<ul class="wp-block-list">
<li><a href="https://public.roboflow.com/object-detection/american-sign-language-letters" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">ASL Alphabet Dataset V1</a></li>



<li><a href="https://github.com/WongKinYiu/yolov7" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">YOLOv7 GitHub repository</a></li>



<li><a href="https://blog.ovhcloud.com/object-detection-train-yolov5-on-a-custom-dataset/" data-wpel-link="internal">Object detection: train YOLOv5 on a custom dataset</a></li>



<li><a href="https://medium.com/@prishanga1/yolov7-training-on-custom-data-c6d8ec030e13" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">YoloV7 Training on Custom Data</a></li>
</ul>
<img loading="lazy" decoding="async" src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fcreate-your-solution-for-sign-language-recognition-with-ovhcloud-ai-tools%2F&amp;action_name=Create%20your%20solution%20for%20Sign%20Language%20recognition%20with%20OVHcloud%20AI%20tools&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Fine-Tuning LLaMA 2 Models using a single GPU, QLoRA and AI Notebooks</title>
		<link>https://blog.ovhcloud.com/fine-tuning-llama-2-models-using-a-single-gpu-qlora-and-ai-notebooks/</link>
		
		<dc:creator><![CDATA[Mathieu Busquet]]></dc:creator>
		<pubDate>Fri, 21 Jul 2023 15:04:00 +0000</pubDate>
				<category><![CDATA[OVHcloud Engineering]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AI Notebooks]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Deep learning]]></category>
		<category><![CDATA[Fine-tuning]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[LLaMa 2]]></category>
		<category><![CDATA[Machine learning]]></category>
		<category><![CDATA[PyTorch]]></category>
		<category><![CDATA[QLoRA]]></category>
		<guid isPermaLink="false">https://blog.ovhcloud.com/?p=25613</guid>

					<description><![CDATA[In this tutorial, we will walk you through the process of fine-tuning LLaMA 2 models, providing step-by-step instructions. All the code related to this article is available in our dedicated GitHub repository. You can reproduce all the experiments with OVHcloud AI Notebooks. Introduction On July 18, 2023, Meta released LLaMA 2, the latest version of [&#8230;]<img src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Ffine-tuning-llama-2-models-using-a-single-gpu-qlora-and-ai-notebooks%2F&amp;action_name=Fine-Tuning%20LLaMA%202%20Models%20using%20a%20single%20GPU%2C%20QLoRA%20and%20AI%20Notebooks&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><em>In this tutorial, we will walk you through the process of fine-tuning <a href="https://ai.meta.com/llama/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">LLaMA 2</a> models, providing step-by-step instructions.</em> </p>



<figure class="wp-block-image aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.ovhcloud.com/wp-content/uploads/2023/07/IMG_1564-1024x538.jpg" alt="Fine-Tuning LLaMA 2 Models with a single GPU and OVHcloud" class="wp-image-25629" width="512" height="269" srcset="https://blog.ovhcloud.com/wp-content/uploads/2023/07/IMG_1564-1024x538.jpg 1024w, https://blog.ovhcloud.com/wp-content/uploads/2023/07/IMG_1564-300x158.jpg 300w, https://blog.ovhcloud.com/wp-content/uploads/2023/07/IMG_1564-768x404.jpg 768w, https://blog.ovhcloud.com/wp-content/uploads/2023/07/IMG_1564.jpg 1199w" sizes="auto, (max-width: 512px) 100vw, 512px" /></figure>



<p class="has-text-align-center wp-block-paragraph"><em>All the code related to this article is available in our dedicated <a href="https://github.com/ovh/ai-training-examples/blob/main/notebooks/natural-language-processing/llm/miniconda/llama2-fine-tuning/llama_2_finetuning.ipynb" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">GitHub repository</a><a href="https://github.com/ovh/ai-training-examples/tree/main/apps/streamlit/speech-to-text" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">.</a> You can reproduce all the experiments with</em> <a href="https://www.ovhcloud.com/en-gb/public-cloud/ai-notebooks/" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">OVHcloud AI Notebooks</a>.</p>



<h3 class="wp-block-heading">Introduction</h3>



<p class="wp-block-paragraph">On July 18, 2023, <a href="https://about.meta.com/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">Meta</a> released <a href="https://ai.meta.com/llama/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">LLaMA 2</a>, the latest version of their <strong>Large Language Model </strong>(LLM).</p>



<p class="wp-block-paragraph">Trained between January 2023 and July 2023 on 2 trillion tokens, these new models outperforms other LLMs on many benchmarks, including reasoning, coding, proficiency, and knowledge tests. This release comes in different flavors, with parameter sizes of <strong>7B</strong>, <strong>13B</strong>, and a mind-blowing <strong>70B</strong>. Models are intended for free for both commercial and research use in English.</p>



<p class="wp-block-paragraph">To suit every text generation needed and fine-tune these models, we will use <a href="https://arxiv.org/abs/2305.14314" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">QLoRA (Efficient Finetuning of Quantized LLMs)</a>, a highly efficient fine-tuning technique that involves quantizing a pretrained LLM to just 4 bits and adding small &#8220;Low-Rank Adapters&#8221;. This unique approach allows for fine-tuning LLMs <strong>using just a single GPU</strong>! This technique is supported by the <a href="https://huggingface.co/docs/peft/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">PEFT library</a>.</p>



<p class="wp-block-paragraph">To fine-tune our model, we will create <em>a</em> <a href="https://www.ovhcloud.com/en-gb/public-cloud/ai-notebooks/" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">OVHcloud AI Notebooks</a> with only 1 GPU.</p>



<h3 class="wp-block-heading">Mandatory requirements</h3>



<p class="wp-block-paragraph">To successfully fine-tune LLaMA 2 models, you will need the following:</p>



<ul class="wp-block-list">
<li>Fill Meta&#8217;s form to <a href="https://ai.meta.com/resources/models-and-libraries/llama-downloads/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">request access to the next version of Llama</a>. Indeed, the use of Llama 2 is governed by the Meta license, that you must accept in order to download the model weights and tokenizer.<br></li>



<li>Have a <a href="https://huggingface.co/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">Hugging Face</a> account (with the same email address you entered in Meta&#8217;s form).<br></li>



<li>Have a <a href="https://huggingface.co/settings/tokens" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">Hugging Face token</a>.<br></li>



<li>Visit the page of one of the LLaMA 2 available models (version <a href="https://huggingface.co/meta-llama/Llama-2-7b-hf" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">7B</a>, <a href="https://huggingface.co/meta-llama/Llama-2-13b-hf" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">13B</a> or <a href="https://huggingface.co/meta-llama/Llama-2-70b-hf" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">70B</a>), and accept Hugging Face&#8217;s license terms and acceptable use policy.<br></li>



<li>Log in to the Hugging Face model Hub from your notebook&#8217;s terminal by running the <code>huggingface-cli login</code> command, and enter your token. You will not need to add your token as git credential.<br></li>



<li>Powerful Computing Resources: Fine-tuning the Llama 2 model requires substantial computational power. Ensure you are running code on GPU(s) when using <a href="https://www.ovhcloud.com/en-gb/public-cloud/ai-notebooks/" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">AI Notebooks</a> or <a href="https://www.ovhcloud.com/en/public-cloud/ai-training/" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">AI Training</a>.</li>
</ul>



<h3 class="wp-block-heading">Set up your Python environment</h3>



<p class="wp-block-paragraph">Create the following <code>requirements.txt</code> file:</p>



<pre class="wp-block-code"><code lang="" class="">torch
accelerate @ git+https://github.com/huggingface/accelerate.git
bitsandbytes
datasets==2.13.1
transformers @ git+https://github.com/huggingface/transformers.git
peft @ git+https://github.com/huggingface/peft.git
trl @ git+https://github.com/lvwerra/trl.git
scipy</code></pre>



<p class="wp-block-paragraph">Then install and import the installed libraries:</p>



<pre class="wp-block-code"><code class="">pip install -r requirements.txt</code></pre>



<pre class="wp-block-code"><code lang="python" class="language-python">import argparse
import bitsandbytes as bnb
from datasets import load_dataset
from functools import partial
import os
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training, AutoPeftModelForCausalLM
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, set_seed, Trainer, TrainingArguments, BitsAndBytesConfig, \
    DataCollatorForLanguageModeling, Trainer, TrainingArguments
from datasets import load_dataset</code></pre>



<h3 class="wp-block-heading">Download LLaMA 2 model</h3>



<p class="wp-block-paragraph">As mentioned before, LLaMA 2 models come in different flavors which are 7B, 13B, and 70B. Your choice can be influenced by your computational resources. Indeed, larger models require more resources, memory, processing power, and training time.</p>



<p class="wp-block-paragraph">To download the model you have been granted access to, <strong>make sure you are logged in to the Hugging Face model hub</strong>. As mentioned in the requirements step, you need to use the <code>huggingface-cli login</code> command.</p>



<p class="wp-block-paragraph">The following function will help us to download the model and its tokenizer. It requires a bitsandbytes configuration that we will define later.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">def load_model(model_name, bnb_config):
    n_gpus = torch.cuda.device_count()
    max_memory = f'{40960}MB'

    model = AutoModelForCausalLM.from_pretrained(
        model_name,
        quantization_config=bnb_config,
        device_map="auto", # dispatch efficiently the model on the available ressources
        max_memory = {i: max_memory for i in range(n_gpus)},
    )
    tokenizer = AutoTokenizer.from_pretrained(model_name, use_auth_token=True)

    # Needed for LLaMA tokenizer
    tokenizer.pad_token = tokenizer.eos_token

    return model, tokenizer</code></pre>



<h3 class="wp-block-heading">Download a Dataset</h3>



<p class="wp-block-paragraph">There are many datasets that can help you fine-tune your model. You can even use your own dataset!</p>



<p class="wp-block-paragraph">In this tutorial, we are going to download and use the <a href="https://huggingface.co/datasets/databricks/databricks-dolly-15k" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">Databricks Dolly 15k dataset</a>, which contains <strong>15,000 prompt/response pairs</strong>. It was crafted by over 5,000 <a href="https://www.databricks.com/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">Databricks</a> employees during March and April of 2023.</p>



<p class="wp-block-paragraph">This dataset is designed specifically for fine-tuning large language models. Released under the <a href="https://creativecommons.org/licenses/by-sa/3.0/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">CC BY-SA 3.0 license</a>, it can be used, modified, and extended by any individual or company, even for commercial applications. So it&#8217;s a perfect fit for our use case!</p>



<p class="wp-block-paragraph">However, like most datasets, this one has <strong>its limitations</strong>. Indeed, pay attention to the following points:</p>



<ul class="wp-block-list">
<li>It consists of content collected from the public internet, which means it may contain objectionable, incorrect or biased content and typo errors, which could influence the behavior of models fine-tuned using this dataset.<br></li>



<li>Since the dataset has been created for Databricks by their own employees, it&#8217;s worth noting that the dataset reflects the interests and semantic choices of Databricks employees, which may not be representative of the global population at large.<br></li>



<li>We only have access to the <code>train</code> split of the dataset, which is its largest subset.</li>
</ul>



<pre class="wp-block-code"><code lang="python" class="language-python"># Load the databricks dataset from Hugging Face
from datasets import load_dataset

dataset = load_dataset("databricks/databricks-dolly-15k", split="train")</code></pre>



<h3 class="wp-block-heading">Explore dataset</h3>



<p class="wp-block-paragraph">Once the dataset is downloaded, we can take a look at it to understand what it contains:</p>



<pre class="wp-block-code"><code lang="python" class="language-python">print(f'Number of prompts: {len(dataset)}')
print(f'Column names are: {dataset.column_names}')

*** OUTPUT ***
Number of prompts: 15011
Column Names are: ['instruction', 'context', 'response', 'category']</code></pre>



<p class="wp-block-paragraph">As we can see, each sample is a dictionary that contains:</p>



<ul class="wp-block-list">
<li><strong>An instruction</strong>: What could be entered by the user, such as a question</li>



<li><strong>A context</strong>: Help to interpret the sample</li>



<li><strong>A response</strong>: Answer to the instruction</li>



<li><strong>A category</strong>: Classify the sample between Open Q&amp;A, Closed Q&amp;A, Extract information from Wikipedia, Summarize information from Wikipedia, Brainstorming, Classification, Creative writing</li>
</ul>



<h3 class="wp-block-heading">Pre-processing dataset</h3>



<p class="wp-block-paragraph"><strong>Instruction fine-tuning</strong> is a common technique used to fine-tune a base LLM for a specific downstream use-case.</p>



<p class="wp-block-paragraph">It will help us to format our prompts as follows: </p>



<pre class="wp-block-code"><code class="">Below is an instruction that describes a task. Write a response that appropriately completes the request.

### Instruction:
Sea or Mountain

### Response:
I believe Mountain are more attractive but Ocean has it's own beauty and this tropical weather definitely turn you on! SO 50% 50%

### End</code></pre>



<p class="wp-block-paragraph">To delimit each prompt part by hashtags, we can use the following function:</p>



<pre class="wp-block-code"><code lang="python" class="language-python">def create_prompt_formats(sample):
    """
    Format various fields of the sample ('instruction', 'context', 'response')
    Then concatenate them using two newline characters 
    :param sample: Sample dictionnary
    """

    INTRO_BLURB = "Below is an instruction that describes a task. Write a response that appropriately completes the request."
    INSTRUCTION_KEY = "### Instruction:"
    INPUT_KEY = "Input:"
    RESPONSE_KEY = "### Response:"
    END_KEY = "### End"
    
    blurb = f"{INTRO_BLURB}"
    instruction = f"{INSTRUCTION_KEY}\n{sample['instruction']}"
    input_context = f"{INPUT_KEY}\n{sample['context']}" if sample["context"] else None
    response = f"{RESPONSE_KEY}\n{sample['response']}"
    end = f"{END_KEY}"
    
    parts = [part for part in [blurb, instruction, input_context, response, end] if part]

    formatted_prompt = "\n\n".join(parts)
    
    sample["text"] = formatted_prompt

    return sample</code></pre>



<p class="wp-block-paragraph">Now, we will use our <strong>model tokenizer to process these prompts into tokenized ones</strong>. </p>



<p class="wp-block-paragraph">The goal is to create input sequences of uniform length (which are suitable for fine-tuning the language model because it maximizes efficiency and minimize computational overhead), that must not exceed the model&#8217;s maximum token limit.</p>



<pre class="wp-block-code"><code lang="python" class="language-python"># SOURCE https://github.com/databrickslabs/dolly/blob/master/training/trainer.py
def get_max_length(model):
    conf = model.config
    max_length = None
    for length_setting in ["n_positions", "max_position_embeddings", "seq_length"]:
        max_length = getattr(model.config, length_setting, None)
        if max_length:
            print(f"Found max lenth: {max_length}")
            break
    if not max_length:
        max_length = 1024
        print(f"Using default max length: {max_length}")
    return max_length


def preprocess_batch(batch, tokenizer, max_length):
    """
    Tokenizing a batch
    """
    return tokenizer(
        batch["text"],
        max_length=max_length,
        truncation=True,
    )


# SOURCE https://github.com/databrickslabs/dolly/blob/master/training/trainer.py
def preprocess_dataset(tokenizer: AutoTokenizer, max_length: int, seed, dataset: str):
    """Format &amp; tokenize it so it is ready for training
    :param tokenizer (AutoTokenizer): Model Tokenizer
    :param max_length (int): Maximum number of tokens to emit from tokenizer
    """
    
    # Add prompt to each sample
    print("Preprocessing dataset...")
    dataset = dataset.map(create_prompt_formats)#, batched=True)
    
    # Apply preprocessing to each batch of the dataset &amp; and remove 'instruction', 'context', 'response', 'category' fields
    _preprocessing_function = partial(preprocess_batch, max_length=max_length, tokenizer=tokenizer)
    dataset = dataset.map(
        _preprocessing_function,
        batched=True,
        remove_columns=["instruction", "context", "response", "text", "category"],
    )

    # Filter out samples that have input_ids exceeding max_length
    dataset = dataset.filter(lambda sample: len(sample["input_ids"]) &lt; max_length)
    
    # Shuffle dataset
    dataset = dataset.shuffle(seed=seed)

    return dataset</code></pre>



<p class="wp-block-paragraph">With these functions, our dataset will be ready for fine-tuning !</p>



<h3 class="wp-block-heading">Create a bitsandbytes configuration</h3>



<p class="wp-block-paragraph">This will allow us to load our LLM in 4 bits. This way, we can divide the used memory by 4 and import the model on smaller devices. We choose to apply bfloat16 compute data type and nested quantization for memory-saving purposes.</p>



<pre class="wp-block-code"><code lang="python" class="language-python">def create_bnb_config():
    bnb_config = BitsAndBytesConfig(
        load_in_4bit=True,
        bnb_4bit_use_double_quant=True,
        bnb_4bit_quant_type="nf4",
        bnb_4bit_compute_dtype=torch.bfloat16,
    )

    return bnb_config</code></pre>



<p class="wp-block-paragraph">To leverage the LoRa method, we need to wrap the model as a PeftModel.</p>



<p class="wp-block-paragraph">To do this, we need to implement a <a href="https://huggingface.co/docs/peft/conceptual_guides/lora" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">LoRa configuration</a>:</p>



<pre class="wp-block-code"><code lang="python" class="language-python">def create_peft_config(modules):
    """
    Create Parameter-Efficient Fine-Tuning config for your model
    :param modules: Names of the modules to apply Lora to
    """
    config = LoraConfig(
        r=16,  # dimension of the updated matrices
        lora_alpha=64,  # parameter for scaling
        target_modules=modules,
        lora_dropout=0.1,  # dropout probability for layers
        bias="none",
        task_type="CAUSAL_LM",
    )

    return config</code></pre>



<p class="wp-block-paragraph">Previous function needs the <strong>target modules</strong> to update the necessary matrices. The following function will get them for our model:</p>



<pre class="wp-block-code"><code lang="python" class="language-python"># SOURCE https://github.com/artidoro/qlora/blob/main/qlora.py

def find_all_linear_names(model):
    cls = bnb.nn.Linear4bit #if args.bits == 4 else (bnb.nn.Linear8bitLt if args.bits == 8 else torch.nn.Linear)
    lora_module_names = set()
    for name, module in model.named_modules():
        if isinstance(module, cls):
            names = name.split('.')
            lora_module_names.add(names[0] if len(names) == 1 else names[-1])

    if 'lm_head' in lora_module_names:  # needed for 16-bit
        lora_module_names.remove('lm_head')
    return list(lora_module_names)</code></pre>



<p class="wp-block-paragraph">Once everything is set up and the base model is prepared, we can use the <em>print_trainable_parameters()</em> helper function to see how many trainable parameters are in the model. </p>



<pre class="wp-block-code"><code lang="python" class="language-python">def print_trainable_parameters(model, use_4bit=False):
    """
    Prints the number of trainable parameters in the model.
    """
    trainable_params = 0
    all_param = 0
    for _, param in model.named_parameters():
        num_params = param.numel()
        # if using DS Zero 3 and the weights are initialized empty
        if num_params == 0 and hasattr(param, "ds_numel"):
            num_params = param.ds_numel

        all_param += num_params
        if param.requires_grad:
            trainable_params += num_params
    if use_4bit:
        trainable_params /= 2
    print(
        f"all params: {all_param:,d} || trainable params: {trainable_params:,d} || trainable%: {100 * trainable_params / all_param}"
    )</code></pre>



<p class="wp-block-paragraph">We expect the LoRa model to have fewer trainable parameters compared to the original one, since we want to perform fine-tuning.</p>



<h3 class="wp-block-heading">Train</h3>



<p class="wp-block-paragraph">Now that everything is ready, we can pre-process our dataset and load our model using the set configurations: </p>



<pre class="wp-block-code"><code lang="python" class="language-python"># Load model from HF with user's token and with bitsandbytes config

model_name = "meta-llama/Llama-2-7b-hf" 

bnb_config = create_bnb_config()

model, tokenizer = load_model(model_name, bnb_config)</code></pre>



<pre class="wp-block-code"><code lang="python" class="language-python">## Preprocess dataset

max_length = get_max_length(model)

dataset = preprocess_dataset(tokenizer, max_length, seed, dataset)</code></pre>



<p class="wp-block-paragraph">Then, we can run our fine-tuning process: </p>



<pre class="wp-block-code"><code lang="python" class="language-python">def train(model, tokenizer, dataset, output_dir):
    # Apply preprocessing to the model to prepare it by
    # 1 - Enabling gradient checkpointing to reduce memory usage during fine-tuning
    model.gradient_checkpointing_enable()

    # 2 - Using the prepare_model_for_kbit_training method from PEFT
    model = prepare_model_for_kbit_training(model)

    # Get lora module names
    modules = find_all_linear_names(model)

    # Create PEFT config for these modules and wrap the model to PEFT
    peft_config = create_peft_config(modules)
    model = get_peft_model(model, peft_config)
    
    # Print information about the percentage of trainable parameters
    print_trainable_parameters(model)
    
    # Training parameters
    trainer = Trainer(
        model=model,
        train_dataset=dataset,
        args=TrainingArguments(
            per_device_train_batch_size=1,
            gradient_accumulation_steps=4,
            warmup_steps=2,
            max_steps=20,
            learning_rate=2e-4,
            fp16=True,
            logging_steps=1,
            output_dir="outputs",
            optim="paged_adamw_8bit",
        ),
        data_collator=DataCollatorForLanguageModeling(tokenizer, mlm=False)
    )
    
    model.config.use_cache = False  # re-enable for inference to speed up predictions for similar inputs
    
    ### SOURCE https://github.com/artidoro/qlora/blob/main/qlora.py
    # Verifying the datatypes before training
    
    dtypes = {}
    for _, p in model.named_parameters():
        dtype = p.dtype
        if dtype not in dtypes: dtypes[dtype] = 0
        dtypes[dtype] += p.numel()
    total = 0
    for k, v in dtypes.items(): total+= v
    for k, v in dtypes.items():
        print(k, v, v/total)
     
    do_train = True
    
    # Launch training
    print("Training...")
    
    if do_train:
        train_result = trainer.train()
        metrics = train_result.metrics
        trainer.log_metrics("train", metrics)
        trainer.save_metrics("train", metrics)
        trainer.save_state()
        print(metrics)    
    
    ###
    
    # Saving model
    print("Saving last checkpoint of the model...")
    os.makedirs(output_dir, exist_ok=True)
    trainer.model.save_pretrained(output_dir)
    
    # Free memory for merging weights
    del model
    del trainer
    torch.cuda.empty_cache()
    
    
output_dir = "results/llama2/final_checkpoint"
train(model, tokenizer, dataset, output_dir)</code></pre>



<p class="wp-block-paragraph"><em>If you prefer to have a number of epochs (entire training dataset will be passed through the model) instead of a number of training steps (forward and backward passes through the model with one batch of data), you can replace the <code>max_steps</code> argument by <code>num_train_epochs</code>.</em></p>



<p class="wp-block-paragraph">To later load and use the model for inference, we have used the <code>trainer.model.save_pretrained(output_dir)</code> function, which saves the fine-tuned model&#8217;s weights, configuration, and tokenizer files.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.ovhcloud.com/wp-content/uploads/2023/07/finetuning-llama2-results-1024x498.png" alt="" class="wp-image-25619" width="870" height="422" srcset="https://blog.ovhcloud.com/wp-content/uploads/2023/07/finetuning-llama2-results-1024x498.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2023/07/finetuning-llama2-results-300x146.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2023/07/finetuning-llama2-results-768x374.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2023/07/finetuning-llama2-results.png 1320w" sizes="auto, (max-width: 870px) 100vw, 870px" /></figure>



<p class="has-text-align-center wp-block-paragraph">Fine-tuning llama2 results on <a href="https://huggingface.co/datasets/databricks/databricks-dolly-15k" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">databricks-dolly-15k</a> dataset</p>



<p class="wp-block-paragraph">Unfortunately, it is possible that the latest weights are not the best. To solve this problem, you can implement a <code>EarlyStoppingCallback</code>, from transformers, during your fine-tuning. This will enable you to regularly test your model on the validation set, if you have one, and keep only the best weights.</p>



<h3 class="wp-block-heading">Merge weights</h3>



<p class="wp-block-paragraph">Once we have our fine-tuned weights, we can build our fine-tuned model and save it to a new directory, with its associated tokenizer. By performing these steps, we can have a memory-efficient fine-tuned model and tokenizer ready for inference!</p>



<pre class="wp-block-code"><code lang="python" class="language-python">model = AutoPeftModelForCausalLM.from_pretrained(output_dir, device_map="auto", torch_dtype=torch.bfloat16)
model = model.merge_and_unload()

output_merged_dir = "results/llama2/final_merged_checkpoint"
os.makedirs(output_merged_dir, exist_ok=True)
model.save_pretrained(output_merged_dir, safe_serialization=True)

# save tokenizer for easy inference
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.save_pretrained(output_merged_dir)</code></pre>



<h3 class="wp-block-heading">Conclusion</h3>



<p class="wp-block-paragraph">We hope you have enjoyed this article!</p>



<p class="wp-block-paragraph">You are now able to fine-tune LLaMA 2 models on your own datasets!</p>



<p class="wp-block-paragraph">In our next tutorial, you will discover how to <strong>Deploy your Fine-tuned LLM on <a href="https://www.ovhcloud.com/en/public-cloud/ai-deploy/" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">OVHcloud AI Deploy</a> for inference</strong>!</p>
<img loading="lazy" decoding="async" src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Ffine-tuning-llama-2-models-using-a-single-gpu-qlora-and-ai-notebooks%2F&amp;action_name=Fine-Tuning%20LLaMA%202%20Models%20using%20a%20single%20GPU%2C%20QLoRA%20and%20AI%20Notebooks&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
