<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Personal Blog</title><link>https://zansf-personal-blog.statichost.page/</link><description/><atom:link href="https://zansf-personal-blog.statichost.page/feeds/rss.xml" rel="self"/><lastBuildDate>Thu, 01 Oct 2026 00:00:00 +0200</lastBuildDate><item><title>Encoding videos to AV1</title><link>https://zansf-personal-blog.statichost.page/encoding-videos-to-av1.html</link><description>&lt;p&gt;Let's just say i was trying to learn how to better use &lt;code&gt;ffmpeg&lt;/code&gt;,
and started asking myself "What are the things i needed when working with video content?".&lt;/p&gt;
&lt;p&gt;And this is one of the things that came to mind.&lt;/p&gt;
&lt;p&gt;I had a bunch of videos, that used the &lt;a href="https://www.itu.int/rec/T-REC-H.264"&gt;H.264&lt;/a&gt; format, taking alot of disk space.
Was looking around for alternative formats, to save space. The best options at that time were VP9 and AV1.
Both compress really well, but AV1 is more aggressive in compressing the video stream, and combined with OPUS audio,
this resulted in better file size reductions while ensuring minimal quality loss.&lt;/p&gt;
&lt;p&gt;Now, regarding container formats to use, i have found so far two options. 
And these are &lt;a href="https://en.wikipedia.org/wiki/WebM"&gt;WebM&lt;/a&gt; and &lt;a href="https://www.matroska.org/what_is_matroska.html"&gt;MKV&lt;/a&gt;.
Choose MKV due to it being one of the best multimedia container formats out there, but any of these two should work fine.&lt;/p&gt;
&lt;h2&gt;Using ffmpeg&lt;/h2&gt;
&lt;p&gt;The most used option to encode a video AFAIK.&lt;/p&gt;
&lt;p&gt;Here is a simple Linux script i made (using the installed &lt;code&gt;ffmpeg&lt;/code&gt; package on Linux Mint) that 
converts whatever video file into a separate &lt;code&gt;.mkv&lt;/code&gt; AV1 encoded video file,
that is rescaled to 720p with solid quality parameters.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="c1"&gt;#################################################&lt;/span&gt;
&lt;span class="c1"&gt;# Encode a video file into the AV1 video format #&lt;/span&gt;
&lt;span class="c1"&gt;# using OPUS audio within a .webm container.    #&lt;/span&gt;
&lt;span class="c1"&gt;#################################################&lt;/span&gt;
ffmpeg&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-codec:v&lt;span class="w"&gt; &lt;/span&gt;libsvtav1&lt;span class="w"&gt; &lt;/span&gt;-vf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;scale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;-1:720&lt;span class="w"&gt; &lt;/span&gt;-crf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;35&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-preset&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-codec:a&lt;span class="w"&gt; &lt;/span&gt;libopus&lt;span class="w"&gt; &lt;/span&gt;-b:a&lt;span class="w"&gt; &lt;/span&gt;192k&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="p"&gt;//.*/.mkv&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;The 1. argument is the input filepath.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The output filepath is the input one, with the suffix changed to &lt;code&gt;.mkv&lt;/code&gt; .&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Thu, 01 Oct 2026 00:00:00 +0200</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-10-01:/encoding-videos-to-av1.html</guid><category>Scripting</category><category>bash_scripting</category><category>format_convertions</category><category>converting_videos</category><category>ffmpeg</category></item><item><title>How i managed to host this blog for free</title><link>https://zansf-personal-blog.statichost.page/how-i-managed-to-host-this-blog-for-free.html</link><description>&lt;p&gt;Before i started to write this blog for real, my biggest problem was "How am i supposed to host this without spending money i barely have?". Hosting itself was ironically not a problem, with GitHub Pages and other free options. But...there was the issue of getting a domain, and these (from what i have seen so far) ALL cost money, monthly!&lt;/p&gt;
&lt;p&gt;And i also wanted to avoid using Wordpress, having ads to finance the hosting+domain, and the blog must be GDPR compliant.&lt;/p&gt;
&lt;p&gt;I am not a cheapskate, but due to the problems in the job markets at the moment in Slovenia and Europe in general, everything is gettting more expensive and the need to conserve money becomes very important. 
Selfhosting was also a option, but i am again stuck with the domain problem, since finding someone with a dynamic IP (even a static IP) address is not exactly great.&lt;/p&gt;
&lt;p&gt;And i happen to &lt;a href="https://www.statichost.eu/blog/statichost-hosting/"&gt;not be the only one trying this out.&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;How the blog is build and hosted&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;It gets build using the &lt;a href="https://getpelican.com/"&gt;Pelican&lt;/a&gt; static site generator from a collection of Markdown articles i write.&lt;/li&gt;
&lt;li&gt;The Pelican output (static webpages) is then deployed/pushed in a Git &lt;a href="https://codeberg.org"&gt;codeberg&lt;/a&gt; repository, when ready.&lt;/li&gt;
&lt;li&gt;The actual hosting is finally done using &lt;a href="https://www.statichost.eu/"&gt;statichost&lt;/a&gt;, which fetches the webpages from the codeberg repository and deployes that as a static webpage, with a sane URL.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It's not much, and &lt;em&gt;keep in mind that i use this blog non-commercially&lt;/em&gt;.
Anyone with abit of Git and Pelican knowhow can make this work.&lt;/p&gt;
&lt;h2&gt;My thoughts to this hosting approach&lt;/h2&gt;
&lt;p&gt;To get a reliable free blog hosting option, with GDPR compliance...this, i think,
is as good as it gets without things getting more complicated or making to many compromises.&lt;/p&gt;
&lt;p&gt;Sure, GitHub Pages and similar can do the same thing, but this is simpler (atleast for me).&lt;/p&gt;
&lt;p&gt;In the end, if your looking for a blog to host, this is one of several options to choose from.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Thu, 01 Oct 2026 00:00:00 +0200</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-10-01:/how-i-managed-to-host-this-blog-for-free.html</guid><category>Hosting</category><category>hosting</category><category>education</category><category>practical</category></item><item><title>How to setup Diffusers for Stable Diffusion XL using a Nvidia Pascal GPU in Linux (Ubuntu or Debian based)</title><link>https://zansf-personal-blog.statichost.page/how-to-setup-diffusers-for-stable-diffusion-xl-using-a-nvidia-pascal-gpu-in-linux-ubuntu-or-debian-based.html</link><description>&lt;p&gt;You need to first ensure that all the necessary drivers (CUDA most important) for the Nvidia GPU are installed. This post will NOT cover how to do that.&lt;/p&gt;
&lt;p&gt;What i am working with here is a Nvidia GTX 1070, just so you know.&lt;/p&gt;
&lt;h2&gt;Preparing the project directory and virtual environment&lt;/h2&gt;
&lt;p&gt;Create a new directory/folder (whichever terminology your familiar with) and &lt;code&gt;cd&lt;/code&gt; to it from a terminal instance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now pay attention here.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Diffusers uses &lt;a href="https://pytorch.org/"&gt;PyTorch&lt;/a&gt; as its backend.
PyTorch has &lt;em&gt;several wheel repositories for different CUDA versions&lt;/em&gt;, and you need to choose for Pascal GPUs the one compatible with CUDA 12.1 or 12.4.&lt;/p&gt;
&lt;p&gt;To get the right working libraries, we need to fetch them from the repository 'https://download.pytorch.org/whl/cu124' using the &lt;code&gt;--index-url&lt;/code&gt; pip CLI parameter/argument.&lt;/p&gt;
&lt;p&gt;Now, to the Diffusers Framework.&lt;/p&gt;
&lt;p&gt;Once the PyTorch things is done,
the only thing to watch out for is ensuring &lt;code&gt;transformers&lt;/code&gt; is fixed at version &lt;code&gt;5.5.0&lt;/code&gt; .
Why is that? My hunch (and days of trying to figure out why my setup broke when i updated my libraries in my virtual environment), 
parts of the &lt;code&gt;transformers&lt;/code&gt; API was changed in later version, and &lt;code&gt;diffusers&lt;/code&gt; didn't take that into account in their newer versions.
From my findings, version &lt;code&gt;5.5.0&lt;/code&gt; was the last working one. Since we want this to just work, 
make sure that you only get THAT version until &lt;code&gt;diffusers&lt;/code&gt; decides to fix this.&lt;/p&gt;
&lt;p&gt;Now, lets get to what to run inside our project directory.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python3&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;venv&lt;span class="w"&gt; &lt;/span&gt;./venv/
./venv/bin/pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;torch&lt;span class="w"&gt; &lt;/span&gt;torchvision&lt;span class="w"&gt; &lt;/span&gt;--index-url&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://download.pytorch.org/whl/cu124&amp;#39;&lt;/span&gt;
./venv/bin/pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;diffusers&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;transformers&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;.5.0&lt;span class="w"&gt; &lt;/span&gt;accelerate&lt;span class="w"&gt; &lt;/span&gt;peft
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This should be all that is needed to get a working virtual environment setup.&lt;/p&gt;
&lt;h2&gt;Using Diffusers for running Stable Diffusion XL models&lt;/h2&gt;
&lt;p&gt;This is now the part in which we need to interact with the Diffusers API.
In this case, a regular Python script will do the job, and so, i build one for my needs.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!./venv/bin/python3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;argparse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;pathlib&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;torch&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;diffusers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;DPMSolverMultistepScheduler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;StableDiffusionXLPipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# Constants.&lt;/span&gt;
&lt;span class="c1"&gt;# ==========&lt;/span&gt;
&lt;span class="n"&gt;IMAGES_BATCH_COUNT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;TORCH_DTYPE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bfloat16&lt;/span&gt;


&lt;span class="c1"&gt;# Prepare and parse the terminal arguments.&lt;/span&gt;
&lt;span class="c1"&gt;# =========================================&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArgumentParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Custom program for text-to-image using Stable Diffusion XL models.&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--model&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Huggingface repository path to the SDXL model weights.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--prompt-path&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;./prompt.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Filepath to the prompt on what to generate.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--negative-prompt-path&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Filepath to the prompt on what NOT to generate. Ignored if not set.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--sampling-steps&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;How many steps are performed in the denoising procedure. More usually result in better image quality.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--guidance-scale&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;6.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;How close it should follow the prompt. Lower values result in more freedom, while higher ones result in more consistency.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--images-count&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;IMAGES_BATCH_COUNT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;How many images should be generated per prompt.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--seed&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;The seed used to set the state of the PRNG. If not set, chooses a random one.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--output-dirpath&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;./txt2img_batch&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Where to store the generated images.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;parsed_args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="c1"&gt;# Prepare the text-to-image pipeline to generate images.&lt;/span&gt;
&lt;span class="c1"&gt;# ======================================================&lt;/span&gt;
&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prompt_path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;negative_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;negative_prompt_path&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;negative_prompt_path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StableDiffusionXLPipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_single_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;custom_pipeline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;lpw_stable_diffusion_xl&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;torch_dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;TORCH_DTYPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;variant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bfp16&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;safety_checker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DPMSolverMultistepScheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;use_karras_sigmas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;algorithm_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;dpmsolver++&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_model_cpu_offload&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_attention_slicing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slice_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;auto&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vae&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_slicing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Generate and save the images.&lt;/span&gt;
&lt;span class="c1"&gt;# =============================&lt;/span&gt;
&lt;span class="n"&gt;batch_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leftover_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;divmod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;images_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IMAGES_BATCH_COUNT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;images_batch_sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;batch_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;images_batch_sequence&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IMAGES_BATCH_COUNT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;batch_count&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;leftover_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;images_batch_sequence&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;leftover_count&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manual_seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dirpath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;num_images_per_prompt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;images_batch_sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;inference_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;negative_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;negative_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;num_inference_steps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sampling_steps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;guidance_scale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;guidance_scale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;num_images_per_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;num_images_per_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;file_counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;saved_image_paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;generated_image&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;inference_result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;output_filepath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dirpath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;joinpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;image&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;file_counter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.png&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;output_filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;file_counter&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="n"&gt;output_filepath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dirpath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;joinpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;image&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;file_counter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.png&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;generated_image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;saved_image_paths&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Saved the generated &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;num_images_per_prompt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; image/s &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;saved_image_paths&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; into the directory &amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dirpath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is what i use to generate AI images with Stable Diffusion XL models.
It has a solid CLI interface, and the script can be adapted for ones individual needs if something is insufficient.&lt;/p&gt;
&lt;p&gt;One important thing to note, due to the Nvidia GTX 1070 being limited to 8 GB of VRAM, and most Stable Diffusion XL models being around 7 GB,
reducing the VRAM usage is a must, and this is done usually with &lt;a href="https://huggingface.co/docs/diffusers/v0.40.0/en/optimization/memory#offloading"&gt;offloading&lt;/a&gt;, &lt;a href="https://huggingface.co/docs/diffusers/v0.40.0/en/optimization/memory#memory-efficient-attention"&gt;attention slicing&lt;/a&gt; and &lt;a href="https://huggingface.co/docs/diffusers/v0.40.0/en/optimization/memory#vae-slicing"&gt;VAE slicing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The best case for offloading is using &lt;a href="https://huggingface.co/docs/diffusers/v0.40.0/en/optimization/memory#model-offloading"&gt;model offloading&lt;/a&gt;, but you need to ensure that &lt;em&gt;almost nothing is filling the GPUs VRAM&lt;/em&gt;, otherwise the script will likely exit with a &lt;em&gt;out of memory exception when saving the generated images&lt;/em&gt;. If that is happening to you way to often, and you have closed all programs, change model offloading to &lt;a href="https://huggingface.co/docs/diffusers/v0.40.0/en/optimization/memory#cpu-offloading"&gt;cpu offloading&lt;/a&gt;. It will take longer, but crashes should happen rarely. Even better (speed and reliability wise) is using &lt;a href="https://huggingface.co/docs/diffusers/v0.40.0/en/optimization/memory#group-offloading"&gt;group offloading&lt;/a&gt; with CUDA streaming enabled, but this required having more RAM (16 GB is not enough, 24+ GB is recommended).&lt;/p&gt;
&lt;p&gt;Regarding attention slicing, it kinda works on the Nvidia GTX 1070, but is &lt;strong&gt;very important to enable&lt;/strong&gt;, since it lowers the VRAM use further, with minimal speed loss.
Now, why it is kinda working? Due to &lt;a href="https://huggingface.co/docs/diffusers/v0.40.0/en/optimization/fp16#scaled-dot-product-attention"&gt;FlashAttention&lt;/a&gt; (the enabled default on newer PyTorch builds) simply not working with my GPU, and a altenative being urgently needed.
My only option (after hours of research and testing) ended up being the &lt;a href="https://huggingface.co/docs/diffusers/v0.40.0/en/api/pipelines/overview#diffusers.DiffusionPipeline.enable_attention_slicing"&gt;enable_attention_slicing&lt;/a&gt; method from the base class &lt;a href="https://huggingface.co/docs/diffusers/v0.40.0/en/api/pipelines/overview#diffusers.DiffusionPipeline"&gt;DiffusionPipeline&lt;/a&gt; class, which does (almost) the same thing luckily, so we are not totally fucked yet.&lt;/p&gt;
&lt;p&gt;VAE slicing saves memory by splitting large batches of inputs into a single batch of data and separately processes them. 
This method works best when generating more than one image at a time, which will be the case most of the time, 
but keep in mind that inference will take longer the more images you generate.&lt;/p&gt;
&lt;h2&gt;Generating images faster using Ays&lt;/h2&gt;
&lt;p&gt;Now this is mostly uncharted territory, but i was researching how to speed up the inference of Stable Diffusion XL models
on my GPU, and found &lt;a href="https://research.nvidia.com/labs/toronto-ai/AlignYourSteps/"&gt;this gem&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, how useful is using the AYS schedule for inference?
In my experience, it is so-so.&lt;/p&gt;
&lt;p&gt;Yes, its much faster and does generate good enough images.
But...the image quality in regards to prompt adherence is worse,
and this depends alot on the model your using.
If it was fine tuned very well, it will perform mostly fine.
If not, the images will most likely look weird.&lt;/p&gt;
&lt;p&gt;Also (from my findings), it is best to use the &lt;a href="https://huggingface.co/docs/diffusers/v0.40.0/en/api/schedulers/multistep_dpm_solver#dpmsolvermultistepscheduler"&gt;sde-dpmsolver++ scheduler&lt;/a&gt;, 
due to it converging faster and giving good quality results, in 10 steps of inference.&lt;/p&gt;
&lt;p&gt;Probably best used for experimenting with new ideas.&lt;/p&gt;
&lt;p&gt;Here is the (mostly) same script, but using AYS for the inference.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!./venv/bin/python3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;argparse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;pathlib&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;torch&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;diffusers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;DPMSolverMultistepScheduler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;StableDiffusionXLPipeline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;diffusers.schedulers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AysSchedules&lt;/span&gt;


&lt;span class="c1"&gt;# Constants.&lt;/span&gt;
&lt;span class="c1"&gt;# ==========&lt;/span&gt;
&lt;span class="n"&gt;IMAGES_BATCH_COUNT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;TORCH_DTYPE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bfloat16&lt;/span&gt;


&lt;span class="c1"&gt;# Prepare and parse the terminal arguments.&lt;/span&gt;
&lt;span class="c1"&gt;# =========================================&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArgumentParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Custom program for text-to-image using normal Stable Diffusion models.&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--model&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Huggingface repository path to the SDXL model weights.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--prompt-path&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;./prompt.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Filepath to the prompt on what to generate.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--negative-prompt-path&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Filepath to the prompt on what NOT to generate. Ignored if not set.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--guidance-scale&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;How close it should follow the prompt. Lower values result in more freedom, while higher ones result in more consistency.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--images-count&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;IMAGES_BATCH_COUNT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;How many images should be generated per prompt.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--seed&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;The seed used to set the state of the PRNG. If not set, chooses a random one.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;--output-dirpath&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;./txt2img_batch&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Where to store the generated images.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;parsed_args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args_parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="c1"&gt;# Prepare the text-to-image pipeline to generate images.&lt;/span&gt;
&lt;span class="c1"&gt;# ======================================================&lt;/span&gt;
&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prompt_path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;negative_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;negative_prompt_path&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;negative_prompt_path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StableDiffusionXLPipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_single_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;custom_pipeline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;lpw_stable_diffusion_xl&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;torch_dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;TORCH_DTYPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;safety_checker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DPMSolverMultistepScheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;algorithm_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;sde-dpmsolver++&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;solver_order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_model_cpu_offload&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_attention_slicing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slice_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;auto&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vae&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable_slicing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="c1"&gt;# Generate and save the images.&lt;/span&gt;
&lt;span class="c1"&gt;# =============================&lt;/span&gt;
&lt;span class="n"&gt;batch_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leftover_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;divmod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;images_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IMAGES_BATCH_COUNT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;images_batch_sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;batch_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;images_batch_sequence&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;IMAGES_BATCH_COUNT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;batch_count&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;leftover_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;images_batch_sequence&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;leftover_count&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manual_seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dirpath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;num_images_per_prompt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;images_batch_sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;inference_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;negative_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;negative_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;guidance_scale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;guidance_scale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;num_images_per_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;num_images_per_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;timesteps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AysSchedules&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;StableDiffusionXLTimesteps&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;file_counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;generated_image&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;inference_result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;output_filepath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dirpath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;joinpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;image&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;file_counter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.png&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;output_filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;file_counter&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="n"&gt;output_filepath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dirpath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;joinpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;image&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;file_counter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.png&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;generated_image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Saved the generated &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;num_images_per_prompt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; image/s into the directory &amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_dirpath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;It's doable, but will get harder with time, due to lacking software support, and whatever currently works will likely no longer be available in the near future,
unless you build the libraries yourself (and even that is sometimes a PITA). How do i know that? Why am i this opinion? &lt;a href="https://github.com/NVIDIA/cuml"&gt;cuML&lt;/a&gt; and &lt;a href="https://github.com/NVIDIA/cudf"&gt;cuDF&lt;/a&gt;. Cannot get binary wheels that have Pascal support,
and building them locally failed with cryptic error messages (maybe my setup sucks, but it is what it is at the moment).
Best i got running is &lt;a href="https://github.com/cupy/cupy/"&gt;cupy&lt;/a&gt; for GPGPU things.&lt;/p&gt;
&lt;p&gt;So, if you wanna do it, you still can, but do not expect miracles, and inference on the Nvidia 1000 series is not the best (the GTX 1070 needs around 3:30 minutes for generating 2 images with model offloading enabled, to give you a idea).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Thu, 01 Oct 2026 00:00:00 +0200</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-10-01:/how-to-setup-diffusers-for-stable-diffusion-xl-using-a-nvidia-pascal-gpu-in-linux-ubuntu-or-debian-based.html</guid><category>Python3</category><category>python3</category><category>diffusers</category><category>stable_diffusion_xl</category><category>generating_ai_images</category><category>linux</category><category>nvidia_pascal_gpu</category></item><item><title>Converting images to webp</title><link>https://zansf-personal-blog.statichost.page/converting-images-to-webp.html</link><description>&lt;p&gt;Let's say i was looking for a way to convert images into a format, that is perfectly suited for webhosting.
That means, decent enough quality and low file size.&lt;/p&gt;
&lt;p&gt;The classics are &lt;code&gt;.jpg&lt;/code&gt; and &lt;code&gt;.png&lt;/code&gt;, which are also the most supported.
But...there is another good one, that is getting better and better support, while providing smaller file sizes.
And that is &lt;a href="https://developers.google.com/speed/webp"&gt;WebP&lt;/a&gt; (there is also &lt;a href="https://aomediacodec.github.io/av1-avif/"&gt;AVIF&lt;/a&gt;, but its less supported).&lt;/p&gt;
&lt;p&gt;From what i know, it was developed by Google and is a good open format.&lt;/p&gt;
&lt;p&gt;Now, there comes just one little problem...converting whatever you have into &lt;code&gt;.webp&lt;/code&gt; is a pain.
So, i have been looking for solutions, and i will share some of them with you.&lt;/p&gt;
&lt;h2&gt;Using ImageMagick&lt;/h2&gt;
&lt;p&gt;Probably easiest to use, but requires the ImageMagick software.
Can also pre and post process images and supports lots of different image formats.
Truly the swiss army knife for image processing over the CLI.&lt;/p&gt;
&lt;p&gt;Here is a simple Linux script (using the installed &lt;code&gt;imagemagick&lt;/code&gt; package on Linux Mint) that 
converts whatever image file into a separate &lt;code&gt;.webp&lt;/code&gt; image file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nv"&gt;image_filepath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;

convert&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;image_filepath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-quality&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;image_filepath&lt;/span&gt;&lt;span class="p"&gt;%.*&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.webp&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Keep you eye out to the &lt;code&gt;-quality&lt;/code&gt; parameter.
This one determines if you want lossless or lossy compression.&lt;/p&gt;
&lt;p&gt;If your image is complex (lets say, landscape with lots of objects),
i recommend using lossy compression and playing with the &lt;code&gt;-quality&lt;/code&gt; parameter abit.
Servers as a alternative to &lt;code&gt;.jpg&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For logos or simpler images, that cannot hide compression artifacts in complex geometry,
just set the &lt;code&gt;-quality&lt;/code&gt; parameter at 100, to get lossless compression.
Servers as a alternative to &lt;code&gt;.png&lt;/code&gt;.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Wed, 30 Sep 2026 00:00:00 +0200</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-09-30:/converting-images-to-webp.html</guid><category>Scripting</category><category>bash_scripting</category><category>format_convertions</category><category>converting_images</category><category>imagemagick</category></item><item><title>Extract clip from video file</title><link>https://zansf-personal-blog.statichost.page/extract-clip-from-video-file.html</link><description>&lt;p&gt;Let's just say i was trying to learn how to better use &lt;code&gt;ffmpeg&lt;/code&gt;,
and started asking myself "What are the things i needed when working with video content?".&lt;/p&gt;
&lt;p&gt;And this is one of the things that came to mind.
A simple way to extract a clip from an starting point and length of a video file, 
and exporting that into another video file with minimal quality loss.&lt;/p&gt;
&lt;p&gt;Here are some ways on how i managed to do exactly that.&lt;/p&gt;
&lt;h2&gt;Using ffmpeg to extract a clip from a specific time point in the video&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="nv"&gt;INPUT_FILEPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;START_TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;CLIP_DURATION_TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;OUTPUT_FILEPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INPUT_FILEPATH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.clip&amp;quot;&lt;/span&gt;

ffmpeg&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-ss&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;START_TIME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INPUT_FILEPATH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-t&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CLIP_DURATION_TIME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-c&lt;span class="w"&gt; &lt;/span&gt;copy&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;OUTPUT_FILEPATH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The Bash script takes 3 arguments in total, with the last being optional:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The 1. one is the filepath to the video file.&lt;/li&gt;
&lt;li&gt;The 2. one is the starting time, from which to extract the clip. The expected input format is &lt;code&gt;HH:MM:SS&lt;/code&gt;, meaning hours, minutes and seconds in two digits.&lt;/li&gt;
&lt;li&gt;The 3. one is the duration of the clip. The expected input format is &lt;code&gt;HH:MM:SS&lt;/code&gt;, meaning hours, minutes and seconds in two digits.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The clipped video file will have the suffix ".clip" added to the output filename.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Wed, 30 Sep 2026 00:00:00 +0200</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-09-30:/extract-clip-from-video-file.html</guid><category>Scripting</category><category>bash_scripting</category><category>ffmpeg</category><category>video_processing</category><category>resources_extraction</category></item><item><title>Extract video frame/s as image</title><link>https://zansf-personal-blog.statichost.page/extract-video-frames-as-image.html</link><description>&lt;p&gt;Let's just say i was trying to learn how to better use &lt;code&gt;ffmpeg&lt;/code&gt;,
and started asking myself "What are the things i needed when working with video content?".&lt;/p&gt;
&lt;p&gt;And this is one of the things that came to mind. A simple way to extract one or several video frames
from a video file, and exporting that into a usable image file.&lt;/p&gt;
&lt;p&gt;Very useful for making thumbnails from video content, showing specific moments and so on.&lt;/p&gt;
&lt;p&gt;Here are some ways on how i managed to do exactly that.&lt;/p&gt;
&lt;h2&gt;Using ffmpeg to extract a single frame from a specific time in the video&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="nv"&gt;INPUT_FILEPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;FRAME_TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;OUTPUT_FILEPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;3&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INPUT_FILEPATH&lt;/span&gt;&lt;span class="p"&gt;//.*/.png&lt;/span&gt;&lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;

ffmpeg&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INPUT_FILEPATH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-ss&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FRAME_TIME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-frames:v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;OUTPUT_FILEPATH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The Bash script takes 3 arguments in total, with the last being optional:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The 1. one is the filepath to the video file.&lt;/li&gt;
&lt;li&gt;The 2. one is the starting time, from which to extract the video frame. The expected input format is &lt;code&gt;HH:MM:SS&lt;/code&gt;, meaning hours, minutes and seconds in two digits.&lt;/li&gt;
&lt;li&gt;The 3. is the output filepath. If not set, will use the input filepath and replace the file extension/suffix with &lt;code&gt;.png&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Using ffmpeg to extract multiple frames from a specific time in the video&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="nv"&gt;INPUT_FILEPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;FRAME_TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;OUTPUT_FILEPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;3&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INPUT_FILEPATH&lt;/span&gt;&lt;span class="p"&gt;//.*/.png&lt;/span&gt;&lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;FRAME_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;4&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;60&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;

ffmpeg&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INPUT_FILEPATH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-ss&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FRAME_TIME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
-frames:v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FRAME_COUNT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;OUTPUT_FILEPATH&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The Bash script takes 4 arguments in total, with the third being optional:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The 1. one is the filepath to the video file.&lt;/li&gt;
&lt;li&gt;The 2. one is the starting time, from which to extract the video frame. The expected input format is &lt;code&gt;HH:MM:SS&lt;/code&gt;, meaning hours, minutes and seconds in two digits.&lt;/li&gt;
&lt;li&gt;The 3. is the output filepath. If not set, will use the input filepath and replace the file extension/suffix with &lt;code&gt;.png&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The 4. one is the amount of frames to extract from the starting time onwards. If not set, will extract a total of 60.&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Tue, 29 Sep 2026 00:00:00 +0200</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-09-29:/extract-video-frames-as-image.html</guid><category>Scripting</category><category>bash_scripting</category><category>ffmpeg</category><category>video_processing</category><category>resources_extraction</category></item><item><title>The Adjustable Grippier Hitch</title><link>https://zansf-personal-blog.statichost.page/the-adjustable-grippier-hitch.html</link><description>&lt;p&gt;&lt;img alt="Adjustable Grippier Hitch" src="https://zansf-personal-blog.statichost.page/static/images/adjustable_grippier_hitch.jpg"&gt;&lt;/p&gt;
&lt;p&gt;A new knot i developed, based on the well known Adjustable Grip Hitch.
Did a &lt;a href="https://discourse.igkt.net/t/proof-of-concept-adjustable-grippier-hitch-new-knot-variation/10112"&gt;post on that in the IGKT forum&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The idea came to me when i asked myself "Can the Adjustable Grip Hitch be improved in some way?" while practicing knot tying with a hank of cordage. I switched to playing around with different ways to tie the Adjustable Grip Hitch, until it hit me. "Why not finish with a extra round turn, towards the line?". And...this is how it came to be, as unromantic as it sounds.&lt;/p&gt;
&lt;p&gt;Now towards its attributes (as far as i tested it). It's main purpose is having a &lt;em&gt;stable adjustable loop&lt;/em&gt;, that &lt;strong&gt;doesn't loose its grip when handled in different angles (more then 90 degrees)&lt;/strong&gt;. This is impossible with any other slide and grip hitch, with the closest to achieve that being the Adjustable Grip Hitch.&lt;/p&gt;
&lt;p&gt;Was tested on grippy (synthetic and natural) and slippery rope (synthetic), and worked fine on both to my suprise. There was abit of slippage with the slippery rope, but it then gripped and stayed put.
In my experience, a first.&lt;/p&gt;
&lt;p&gt;Now, this knot has not been tested in situations where someones life is on the balance, so i advice to &lt;strong&gt;NOT use it for climbing or similar&lt;/strong&gt;, until it's been further pressure tested from different sources.&lt;/p&gt;
&lt;p&gt;Here is a video on &lt;a href="https://rumble.com/v7bs10k-proof-of-concept-knot-adjustable-grippier-hitch.html"&gt;how to tie it&lt;/a&gt;, for those interested.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Tue, 29 Sep 2026 00:00:00 +0200</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-09-29:/the-adjustable-grippier-hitch.html</guid><category>Knot Tying</category><category>knots</category><category>education</category><category>practical</category></item><item><title>Using GNU parallel to automate git pull of GitHub repositories</title><link>https://zansf-personal-blog.statichost.page/using-gnu-parallel-to-automate-git-pull-of-github-repositories.html</link><description>&lt;p&gt;I personally have cloned hundreds of git repositories of various FOSS and FLOSS projects (for personal needs),
and these, of course, should preferably have the latest changes available.&lt;/p&gt;
&lt;p&gt;Doing manual &lt;code&gt;git pull&lt;/code&gt; commands in each repository separately is insane, and my first effort to automate it proven to be to slow (one pull per repo at a time).&lt;/p&gt;
&lt;p&gt;Started researching ways to speed this up in a sane manner, and found &lt;a href="https://www.gnu.org/software/parallel/"&gt;GNU parallel&lt;/a&gt;.
Fits the usecase nicely, and so, i started to experiment with it, to see, if it is up to the task practically.
Proven to offer what i need, the same Bash script was rewritten by using &lt;code&gt;parallel&lt;/code&gt; in combination with &lt;code&gt;find&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Damn thing ended up being much faster then expected and the git repositories were updated in minutes instead of nearly more then 15 minutes.
This was done on a NVME SSD (works OK on a HDD, but don't expect a near x10 speedup).&lt;/p&gt;
&lt;p&gt;For anyone interested in the script, here it is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="nv"&gt;NUMBER_OF_PROCESSES_TO_USE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Seeking the git repos within this directory...&amp;#39;&lt;/span&gt;
&lt;span class="nv"&gt;LOCAL_GIT_REPOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;find&lt;span class="w"&gt; &lt;/span&gt;-type&lt;span class="w"&gt; &lt;/span&gt;d&lt;span class="w"&gt; &lt;/span&gt;-name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;.git&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-exec&lt;span class="w"&gt; &lt;/span&gt;dirname&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;;&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;NUMBER_OF_GIT_REPOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LOCAL_GIT_REPOS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;wc&lt;span class="w"&gt; &lt;/span&gt;--lines&lt;span class="k"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Starting to pull the latest remote changes for &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NUMBER_OF_GIT_REPOS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; git repositories (see &amp;#39;jobs completed&amp;#39; for the current progress).&amp;quot;&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LOCAL_GIT_REPOS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
parallel&lt;span class="w"&gt; &lt;/span&gt;-j&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NUMBER_OF_PROCESSES_TO_USE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--progress&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;git -C {} pull --all --recurse-submodules &amp;amp;&amp;gt; /dev/null&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It basically searches from the current working directory the git repositories, that are stored in it, and stores their filepaths (newline delimited) in a Bash variable.
Then, those filepaths get feed to &lt;code&gt;parallel&lt;/code&gt;, which executes the &lt;code&gt;git pull&lt;/code&gt; command with some additional parameters.
Not very complicated, but it took some time to get it to run reliably, since i didn't fully understand &lt;code&gt;parallel&lt;/code&gt; yet.&lt;/p&gt;
&lt;p&gt;Hope this helps anyone who is working on something similar.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Tue, 29 Sep 2026 00:00:00 +0200</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-09-29:/using-gnu-parallel-to-automate-git-pull-of-github-repositories.html</guid><category>Scripting</category><category>bash_scripting</category><category>gnu_tools</category><category>git</category><category>parallel</category></item><item><title>My thoughts on the human mind</title><link>https://zansf-personal-blog.statichost.page/my-thoughts-on-the-human-mind.html</link><description>&lt;p&gt;The human mind is really fascinating.&lt;/p&gt;
&lt;p&gt;My personal thoughts on the mind is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is a self-actualizing mini-universe, build upon the persons perception of reality.&lt;/li&gt;
&lt;li&gt;The people one meets and interacts with get imperfectly replicated (you could argue, into a ghost) and become part of their mini-universe, being to some degree subconsciously influenced by them.&lt;/li&gt;
&lt;li&gt;The mind itself hallucinates the things the person couldn't capture from their observation of reality, and fills those blanks with that (however absurd these may be), to fill the blanks.&lt;/li&gt;
&lt;li&gt;The mind doesn't want/cannot to be directly controlled, but &lt;strong&gt;can be directed&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Thu, 24 Sep 2026 00:00:00 +0200</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-09-24:/my-thoughts-on-the-human-mind.html</guid><category>Philosophy</category><category>human_mind</category></item><item><title>Why IoT devices are overrated</title><link>https://zansf-personal-blog.statichost.page/why-iot-devices-are-overrated.html</link><description>&lt;p&gt;IoT (Internet of Things)...&lt;/p&gt;
&lt;p&gt;I personally &lt;strong&gt;never liked them&lt;/strong&gt;. You give to much control to the manufacturer, and most of the internet functionality is not that useful (mostly being remote access).
And they are also targets for cyberattacks (from what i read, usually used to make them part of botnets).&lt;/p&gt;
&lt;p&gt;This doesn't mean that they are useless. Just...the way they are developed and released makes me despise them.&lt;/p&gt;
&lt;p&gt;They can be made better by making the &lt;em&gt;Internet centric functionality&lt;/em&gt; &lt;strong&gt;optional and non-intrusive&lt;/strong&gt;.
And also offering to the end-user guides on how to maintain them (both hardware and software), when they are discontinued. Also, making the devices as &lt;em&gt;privacy-friendly as possible&lt;/em&gt;, but that is to much to ask for these days, due to how selling your data is a way to make some money, and these IoT devices are usually quick-to-market products for a quick cash grab.&lt;/p&gt;
&lt;p&gt;Been thinking personally on how to design the optimal IoT device, since just complaining gets nothing done.
With that in mind, i came to the following things to keep in mind for developing one:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The hardware must be something that is readily available, affordable, easy to replace and service.&lt;/li&gt;
&lt;li&gt;The software must be developed with FOSS/FLOSS components, that are fully free and open source. This is not for charity, but to keep it running, even when it gets discontinued. Also shows to people, that your product is trustworthy, by being transparent.&lt;/li&gt;
&lt;li&gt;Keep the Internet-centric functions optional, and make them &lt;em&gt;actually provide value&lt;/em&gt; to the end-user.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not requiring a smartphone app for using it&lt;/strong&gt; (THIS is my biggest gripe). And if an external user interface is needed, please, &lt;em&gt;stop requiring the user to create a account on their device&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Thu, 24 Sep 2026 00:00:00 +0200</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-09-24:/why-iot-devices-are-overrated.html</guid><category>Rants</category><category>iot</category><category>rant</category></item><item><title>My knots "Compact Series"</title><link>https://zansf-personal-blog.statichost.page/my-knots-compact-series.html</link><description>&lt;p&gt;There are just to many knots to know about, but which do the job while not being overly complicated and easy to tie and untie,
the list will usually be some derivative of the most popular nautical and scouting knots.&lt;/p&gt;
&lt;p&gt;While these are quite good, i am not satisfied. And new types of knots have been developed,
that could prove very useful if put to use (like the Icicle Hitch and Adjustable Grip Hitch).&lt;/p&gt;
&lt;p&gt;So i went ahead and studied different types of knots, both old and new, and started making notes on
which is for what purpose best, and how good it is compared to equivalent ones.&lt;/p&gt;
&lt;p&gt;Important thing that needed to be demonstrated are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The fewest number of knots that cover 90 % of usecases.&lt;/li&gt;
&lt;li&gt;Teaches the basics.&lt;/li&gt;
&lt;li&gt;Simple to teach.&lt;/li&gt;
&lt;li&gt;Reasonably easy to tie and untie.&lt;/li&gt;
&lt;li&gt;Hold stable on most types of rope.&lt;/li&gt;
&lt;li&gt;Can be used as the basis to learn more complex knots.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first point ended up being the hardest. Each knot is on its own good, but to cover a this large amount of usecases was just unrealistic.
Ended up iteratively studying different types of knots and playing around with them, assesing their qualities and properties.
With each iteration (repeated or not), i got a better understanding of what knot will do the job.
Ended up with a list of 7 knots, and went through many iterations, and its these 7 that stuck.&lt;/p&gt;
&lt;p&gt;They are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Round Turn and Two Half Hitches&lt;/li&gt;
&lt;li&gt;Clove Hitch&lt;/li&gt;
&lt;li&gt;Square Knot&lt;/li&gt;
&lt;li&gt;Fishermen's Bend&lt;/li&gt;
&lt;li&gt;Adjustable Grip Hitch&lt;/li&gt;
&lt;li&gt;Bowline Knot&lt;/li&gt;
&lt;li&gt;Trucker's Hitch&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They teach nearly all basic forms, lead to their more complex counterparts smoothly,
and will work reliably without many hickups.&lt;/p&gt;
&lt;p&gt;I am very proud to have managed to get this list created,
and hope that it helps people in their pursuits.&lt;/p&gt;
&lt;h2&gt;The knots described&lt;/h2&gt;
&lt;h3&gt;Round Turn and Two Half Hitches&lt;/h3&gt;
&lt;p&gt;A basic nautical hitch.&lt;/p&gt;
&lt;p&gt;It teaches the round turn and its utility, the Half Hitch and what happens if you tie two Half Hitches one after another.
Also, that the two Half Hitches make a stable tieoff.&lt;/p&gt;
&lt;h3&gt;Clove Hitch&lt;/h3&gt;
&lt;p&gt;A basic nautical hitch for being tied to a pole.&lt;/p&gt;
&lt;p&gt;It teaches that the Half Hitches can have different configurations with abit of creativity.&lt;/p&gt;
&lt;h3&gt;Square Knot&lt;/h3&gt;
&lt;p&gt;A basic knot, that is also a tieoff.&lt;/p&gt;
&lt;p&gt;Teaches the Half Knot, and what happens if two Half Knots are tied one after another.&lt;/p&gt;
&lt;h3&gt;Fishermens Knot&lt;/h3&gt;
&lt;p&gt;Basic bend for making slings or joining ropes of similar diameter.&lt;/p&gt;
&lt;p&gt;Teaches the overhand knot, its use as a stopper knot, and what happens if two of such stopper knots are tied in opposing positions.&lt;/p&gt;
&lt;h3&gt;Adjustable Grip Hitch&lt;/h3&gt;
&lt;p&gt;Multipurpose adjustable endloop.&lt;/p&gt;
&lt;p&gt;Uses the round turn to prepare the initial loop, before being finished off with a well-placed Half Hitch.&lt;/p&gt;
&lt;h3&gt;Bowline Knot&lt;/h3&gt;
&lt;p&gt;Fixed endloop.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Žan Šadl Ferš</dc:creator><pubDate>Thu, 22 Jan 2026 16:20:00 +0100</pubDate><guid>tag:zansf-personal-blog.statichost.page,2026-01-22:/my-knots-compact-series.html</guid><category>Knot Tying</category><category>knots</category><category>education</category><category>practical</category></item></channel></rss>