Compare commits

..
52 Commits
Author SHA1 Message Date
me c6a309ec82 ollama-benchmark, fixes after doing a few more tests. 2026-10-31 07:55:11 -07:00
me ffbf55c1ed ollama-test, add colors and mention which context and thread count the winners were at. 2026-10-24 21:35:17 -07:00
me ccdc7ea5ed ollama-test, fix number of hyphens under header line. 2026-10-24 20:55:15 -07:00
me f3da185fb6 ollama-test, enhance to me like pv-test with the parameter looping, also fix some variables being set via env and add QUIET to suppress all but the table. 2026-10-24 20:41:38 -07:00
me 933e00556c ollama-test, fix the time comparison to look for the lowest. 2026-10-24 14:30:07 -07:00
me a47d1ab9f8 ollama_benchmark, add a much more capable function for testing ollama models. 2026-10-24 14:17:21 -07:00
me 9a85425c3f llms, import some functions from env-ansible project. 2026-10-24 10:55:37 -07:00
me 95ea82e842 pv3, final update hopefully, looking great and not taking too long to compile, feeling done with all the pv-tests. 2026-10-21 04:45:49 -07:00
me 99b5d6fd6d Add aliases for getting and pushing clones. 2026-09-28 15:30:59 -07:00
me 62f0f072f4 pv-test, fix indent issue from web. 2026-09-19 09:49:06 -07:00
me 6e9288e5c2 pv-test, change scale for libsvtav1 presets, plus add comments. 2026-09-18 18:42:18 -07:00
me 5f0144ed1d pv-test, add comment as to why b:v is not being used for AV1 if only a bitrate is provided. 2026-09-18 09:33:54 -07:00
me 1f5d51e45a pv-test, stop padding the bitrate. 2026-09-16 11:31:00 -07:00
me a5e1dd6a36 pv-test, add ability to specift the basename and automatically have the bitrate appended to the filename (without harming ability to detect completion of previous test). 2026-09-16 11:29:47 -07:00
me 274d4fadef vcompare, add note to move from shared to ansible. 2026-09-15 18:21:29 -07:00
me 5d6338533d pv3, add v5 with higher vbr and longer run time. 2026-09-15 18:16:49 -07:00
me da0d15348c Add vcompare, a shortcut for having two videos play side by side in mpv. 2026-09-15 18:11:21 -07:00
me 9ce76da18d pv3, a few more tweaks as we learn more about AV1. 2026-09-15 17:52:41 -07:00
me c3d845e98e lobsters, add embedded URL. 2026-09-15 16:25:21 -07:00
me 5f13c6624b pv-test, refactor some and change default recommended codecs. 2026-09-15 15:57:58 -07:00
me 13c542b888 pv-test, fix broken loop variable, change loop guess to be multiplication rather than actual loops, add loop counter to output. 2026-09-15 15:42:15 -07:00
me 694767abd5 pv3, fix indentation. pv-test, fix VBR on AV1 to be more testable while also adding capped CRF as an option (changes not yet fully tested). 2026-09-15 10:08:52 -07:00
me 0a88e173fb pv3, try fixing scale issue. 2026-09-15 08:02:31 -07:00
me 2ee0fd2c31 pv3, change tbr (target bitrate) to 1000k and allow overshoot to still take it to 2000k like doing with h264. 2026-09-15 07:12:39 -07:00
me fd2720eb6c pv3, speed up while also using more compressed crf. 2026-09-15 07:01:43 -07:00
me 6f2e18e2f1 pv3, add comment. 2026-09-14 19:01:41 -07:00
me 8e4919b689 pv3, fix av1 codec and add betteroutput. 2026-09-14 18:59:11 -07:00
me 0f42f92eaf Delete swp file. 2026-09-14 18:51:01 -07:00
me 2b7253ade2 pv3, fix codec flags. 2026-09-14 18:50:23 -07:00
me 224e112340 Add pv3. 2026-09-14 18:47:21 -07:00
me be5251ae3a pv-test, show ffprobe info for reference of source data. 2026-09-14 18:30:06 -07:00
me fa11113b2c pv-test, add date to start message. 2026-09-14 18:01:14 -07:00
me 3ac932e42b pv-test, fix committing final file, fix checking for finished versions, add welcome message. 2026-09-14 17:00:19 -07:00
me 701dfbcc96 pv-test, continuing the usability and output enhancements. Now recognizes if an unfinished version needs re-done, if the finished test already exists, and checks ffmpeg status before committing the file. 2026-09-14 16:42:49 -07:00
me da0be0ab41 pv-test, another large refactor which allows typing custom tests in while keeping some loops as questions, enhanced output and the handling of loop indentation, use more -n checks to avoid whitespace issues. 2026-09-14 15:52:03 -07:00
me 7463e4a9b8 pv-test, fix looped files from going to input folder, like done for pv. 2026-09-14 12:46:02 -07:00
me 8279cb8618 pv-test, better handling of vpresets. 2026-09-14 12:43:01 -07:00
me ea0c329d3b pv-test, reword the final confirmation. 2026-09-14 10:53:24 -07:00
me 4b34fd3fd3 pv-test, minor output changes around the final confirmation. 2026-09-14 10:50:52 -07:00
me c2c04ead5d pv-test, remove deleteme code. 2026-09-14 10:47:59 -07:00
me c8b0684433 pv-test, fixes and small enhancements via web.
pv-test, fix pv and pv2 outfile location if path in filename, test defaults for each option by keeping the skip, fix some spacing issues.
2026-09-14 10:46:23 -07:00
me f0e8125109 pv-test, huge rework to allow much better dynamic testing rather than manually commenting for loops and changing values, added automated tests for pv and pv2. 2026-09-14 10:22:30 -07:00
me 3c01ed7331 pv-test, add the proper bitrate method for av1, fix a few output issues, skip testing other bitrates for now. 2026-09-14 07:44:20 -07:00
me 94415ac734 pv-test, add seconds to filename, fix minute padding. 2026-09-08 17:43:05 -07:00
me 5755261150 pv-test, only provide warning and error output from ffmpeg. 2026-09-08 17:36:20 -07:00
me 0eb5c6ea70 pv-test, mp4 vs mkv is moot, use the open source variant (mkv) since barely changes the file size. 2026-09-08 17:10:02 -07:00
me 4b647d5e09 pv-test, use the correct codec for opus audio (libopus). 2026-09-08 17:06:02 -07:00
me 5e1505ce0a pv-test, fix the filenames missing variables. 2026-09-08 09:16:59 -07:00
me c3afb3fcf8 pv-test, fix bugs to the point of having ffmpeg successfully running now. 2026-09-08 08:45:04 -07:00
me bb08f1ef94 pv-test, finish the function, still needs tested. 2026-09-08 08:24:30 -07:00
me a105916ab5 pv-test, add untested function. 2026-09-07 12:26:09 -07:00
me 753611fb67 git-check, use the main branch for wiki projects. 2026-08-24 16:36:18 -07:00
+933 -3
View File
@@ -326,6 +326,8 @@ function send-masters {
} }
alias push-masters="send-masters" alias push-masters="send-masters"
alias sync-masters="send-masters" alias sync-masters="send-masters"
alias push-all="send-masters"
alias send-all="send-masters"
function pull-clones { function pull-clones {
echo -e "`date` - Looping through clone directories." echo -e "`date` - Looping through clone directories."
@@ -339,6 +341,8 @@ function pull-clones {
} }
alias get-clones="pull-clones" alias get-clones="pull-clones"
alias sync-clones="pull-clones" alias sync-clones="pull-clones"
alias pull-all="pull-clones"
alias get-all="pull-clones"
function sync-all { function sync-all {
push-masters push-masters
@@ -771,6 +775,499 @@ alias vta="v2a"
alias pull-audio="v2a" alias pull-audio="v2a"
alias pa="v2a" alias pa="v2a"
# Run all the different codecs, wrappers, bitrates, etc on a file.
function pv-test {
echo -e "Welcome! Let's get your tests set up...\n"
## Input ##
filename_in="$1"
while [[ -z "$filename_in" ]]; do
read -p "Please provide the filename: " filename_in
done
# Existing Functions #
declare -l pv{,2}="n"
typeset -l test_pv{,2}
read -p "Create a test with current 'pv' function? (y/N) " test_pv
if [[ "$test_pv" == "y"* ]]; then
pv="y"
echo " great, will run pv"
else
echo " skipping"
fi
echo " "
read -p "Create a test with current 'pv2' function? (y/N) " test_pv2
if [[ "$test_pv2" == "y"* ]]; then
pv2="y"
echo " great, will run pv2"
else
echo " skipping"
fi
echo " "
# Loop Data #
declare -l {vpreset,crf,vbr,abr,achannel,afreq,over,under}s="default"
echo -e " * * Loop Settings * * \n"
basename="`basename "$filename_in"`"
basename_in=""
read -p "Would you like to specify a basename? [$basename] " basename_in
if [[ -n "$basename_in" ]]; then
basename="$basename_in"
fi
echo -e " basename: '$basename'\n"
typeset -i size_in
read -p "What display ratio would you like to use? [720] " size_in
if (( $size_in == 0 )); then
size_in=720
fi
echo -e " size: '$size_in'\n"
vcodecs="libsvtav1"
read -p "Please provide the video codecs to test: [$vcodecs] " test_vcodecs
if [[ -n "$test_vcodecs" ]]; then
vcodecs="$test_vcodecs"
fi
echo -e " video codecs: '$vcodecs'\n"
echo "Please provide any presets to use."
echo "(if testing both H264 and AV1, please select from: vsl slr slw med fst fsr vft)"
read -p "Add any presets? [$vpresets] " test_vpresets
if [[ -n "$test_vpresets" ]]; then
vpresets="$test_vpresets"
fi
echo -e " presets: '$vpresets'\n"
read -p "Please provide any CRFs to test: [default] " test_crfs
if [[ -n "$test_crfs" ]]; then
crfs="$test_crfs"
fi
echo -e " CRFs: '$crfs'\n"
read -p "Please provide any video bitrates to test: [default] " test_vbrs
if [[ -n "$test_vbrs" ]]; then
vbrs="$test_vbrs"
fi
echo -e " video bitrates: '$vbrs'\n"
if [[ "$vcodecs" == *"libsvtav1"* ]]; then
read -p "Please provide any over percentages for libsvtav1: [default] " test_overs
if [[ -n "$test_overs" ]]; then
overs="$test_overs"
fi
echo -e " over percentages: '$overs'\n"
read -p "Please provide any under percentages for libsvtav1: [default] " test_unders
if [[ -n "$test_unders" ]]; then
unders="$test_unders"
fi
echo -e " under percentages: '$unders'\n"
fi
acodecs="libopus"
read -p "Please provide the audio codecs to test: [$acodecs] " test_acodecs
if [[ -n "$test_acodecs" ]]; then
acodecs="$test_acodecs"
fi
echo -e " audio codecs: '$acodecs'\n"
read -p "Please provide any audio bitrates to test: [default] " test_abrs
if [[ -n "$test_abrs" ]]; then
abrs="$test_abrs"
fi
echo -e " audio bitrates: '$abrs'\n"
read -p "Test both mono and stereo audio channels? (y/N) " test_achannels
if [[ "$test_achannels" == "y"* ]]; then
achannels="1 2" # 1 is mono, 2 is stereo
fi
echo -e " audio channels: '$achannels'\n"
read -p "Test both 48 and 44.1 kHz audio frequencies? (y/N) " test_afreqs
if [[ "$test_afreqs" == "y"* ]]; then
afreqs="48000 44100" # 48 typically found in videos, 44.1 in audio.
fi
echo -e " audio frequencies: '$afreqs'\n"
normalize=""
typeset -u normalize_in
read -p "Would you like to normalize the audio? (Y/n) " normalize_in
if [[ "$normalize_in" != "N"* && $normalize_in != "F"* ]]; then
normalize="-filter:a dynaudnorm=f=33:g=65:p=0.66:m=33.3"
fi
echo -e " normalize: '$normalize'\n"
exts="mkv"
read -p "Please provide the containers to test with: [$exts] " test_exts
if [[ -n "$test_exts" ]]; then
exts="$test_exts"
fi
echo -e " extensions: '$exts'\n"
bitrate_check=""
typeset -u bitrate_in
read -p "Would you like to append the bitrate to the filename? (Y/n) " bitrate_in
if [[ "$bitrate_in" != "N"* && $bitrate_in != "F"* ]]; then
bitrate_check="Y"
fi
echo -e " bitrate_check: '$bitrate_check'\n"
# Final Check #
echo -e " * * Confirmation * * \n"
ffprobe -i "$filename_in"
echo -e "\n * Testing against '$filename_in' above. * \n"
typeset -i guess
guess=$(( \
`wc -w <<< $vcodecs` * `wc -w <<< $vpresets` * `wc -w <<< $crfs` \
* `wc -w <<< $vbrs` * `wc -w <<< $overs` * `wc -w <<< $unders` \
* `wc -w <<< $acodecs` * `wc -w <<< $abrs` \
* `wc -w <<< $achannels` * `wc -w <<< $afreqs` \
))
if (( $guess > 0 )); then
plural=""
if (( $guess != 1 )); then
plural="s"
fi
echo -e "Expecting ${guess} loop${plural}.\n"
else
echo "ERROR: Something went wrong, got 0 loops, exiting."
return 1
fi
typeset -u okay
read -p "Does everything look okay? (Y/n) " okay
if [[ "$okay" == "N" || "$okay" == "F"* ]]; then
echo " Not okay, aborting."
return 1
fi
echo -e "Sounds good, here we go!\n"
## Main ##
if [[ "$pv" == "y" ]]; then
echo " * Starting pv... * "
filename_pv="$(basename "${filename_in}-pv.mkv")"
if [[ -e "$filename_pv" ]]; then
mv -v "$filename_pv" ~/TRASH
fi
pv "$filename_in" "$filename_pv"
echo -e " * Testing with 'pv' complete! * \n"
fi
if [[ "$pv2" == "y" ]]; then
echo " * Starting pv2... * "
filename_pv2="$(basename "${filename_in}-pv2.mkv")"
if [[ -e "$filename_pv2" ]]; then
mv -v "$filename_pv2" ~/TRASH
fi
pv "$filename_in" "$filename_pv2"
echo -e " * Testing with 'pv2' complete! * \n"
fi
typeset -i count
unset vcodec vpreset crf vbr acodec abr ext
for vcodec in $vcodecs; do for vpreset in $vpresets; do for crf in $crfs; do
for vbr in $vbrs; do for over in $overs; do for under in $unders; do
for acodec in $acodecs; do for abr in $abrs;
do for achannel in $achannels; do for afreq in $afreqs; do
for ext in $exts; do
(( count++ ))
preset=""
if [[ "$vpreset" != "default" ]]; then
if [[ "$vcodec" == "libsvtav1" ]]; then
# Scale goes from 0 to 13, 0 being like x264's "placebo", above 8 being destructive.
# Each step down is about 2x as slow, so 6 to 4 is ~4x slower, 6 to 2 is ~16x slower.
case $vpreset in
vsl) preset="2" ;; # best quality; quite slow, but still feasible
slr) preset="3" ;; # nearly the same as 4 but twice as slow
slw) preset="4" ;; # great quality; decent speed
med) preset="6" ;; # good quality; great speed
fst) preset="8" ;; # default; quite fast
fsr) preset="9" ;; # rough drafts only
vft) preset="10" ;; # real time encoding for livestreams
*) preset="$vpreset" ;;
esac
else
case $vpreset in
vsl) preset="veryslow" ;;
slr) preset="slower" ;;
slw) preset="slow" ;;
med) preset="medium" ;; # default
fst) preset="fast" ;;
fsr) preset="faster" ;;
vft) preset="veryfast" ;;
*) preset="$vpreset" ;;
esac
fi
if [[ -n "$preset" ]]; then
preset="-preset $preset"
fi
fi
bitrate=""
if [[ "$crf" != "default" ]]; then
bitrate="-crf $crf"
fi
declare {o,u}fn=""
if [[ "$vbr" != "default" ]]; then
if [[ "$vcodec" == "libsvtav1" ]]; then
#bitrate="$bitrate -svtav1-params rc=1:tbr=$vbr:overshoot-pct=0:undershoot-pct=100"
declare {o,u}=""
if [[ "$over" != "default" ]]; then
o=":overshoot-pct=${over}"
ofn="-o${over}"
fi
if [[ "$under" != "default" ]]; then
u=":undershoot-pct=${under}"
ufn="-u${under}"
fi
if [[ "$crf" == "default" ]]; then
# Variable Bitrate, rate passed should be the TARGET, not the max.
# Can control the params which allow the target to go up and down, but defaults are okay.
# Seems better to not try and force this to imitate "-b:v -minrate -maxrate -bufsize"
# Will definitely want to use a slower preset to ensure the quality stays consistent.
# Can be done like this if not changing over or under.
#bitrate="-b:v $vbr"
# Prefer this method so we know we're doing VBR (rc=1) not CBR (rc=2).
# rc=1, over defaults to 25, under defaults to 50
# rc=2, over defaults to 25, under defaults to 25
bitrate="-svtav1-params rc=1:tbr=${vbr}${o}${u}"
else
# Capped CRF, when both a CRF and bitrate are passed.
# Better to use high CRF with low BR than high BR with low CRF (produces artifacts/tearing).
bitrate="-svtav1-params rc=0:crf=${crf}:mbr=${vbr}${o}${u}"
fi
else
bitrate="$bitrate -b:v $vbr -minrate 0 -maxrate $vbr -bufsize $vbr"
fi
fi
fidelity=""
if [[ "$abr" != "default" ]]; then
fidelity="-b:a $abr"
fi
channel=""
if [[ "$achannel" != "default" ]]; then
channel="-ac $achannel"
fi
frequency=""
if [[ "$afreq" != "default" ]]; then
if [[ "$acodec" == "libopus" ]]; then
case $afreq in
48000) ;; 24000) ;; 16000) ;; 12000) ;; 8000) ;;
*) echo -e "ERROR: libopus cannot do this, skipping frequency ${afreq}."
continue
;;
esac
fi
frequency="-ar $afreq"
fi
ext=".$ext"
newfile="_${size_in}p_${vcodec}-${vpreset}-${crf}-${vbr}${ofn}${ufn}_${acodec}-${abr}-${achannel}-${afreq}${ext}"
echo -e " * [Loop $count/$guess] Parameters for this test: $newfile * \n"
if [[ -e "$newfile" ]]; then
mv -v "$newfile" ~/TRASH/
echo -e "Removed unfinished version of this file.\n"
fi
if [[ `ls *"${newfile//$ext/}"*"$ext"* 2>/dev/null` ]]; then
echo -e "Completed version of this file already exists, skipping.\n"
continue
fi
echo "$(date) - Starting run..."
start=$SECONDS
set -x
ffmpeg -nostdin -hide_banner -loglevel level+warning \
-i "$filename_in" \
-filter:v scale=-1:$size_in \
-c:v $vcodec \
$preset \
$bitrate \
-c:a $acodec \
$fidelity \
$channel \
$frequency \
$normalize \
-movflags +faststart \
"$newfile"
status="$?"
set +x
finish=$SECONDS
minutes=$(( (finish - start) / 60 ))
seconds=$(( (finish - start) % 60 ))
printf -v padded_mins "%03d" "$minutes"
printf -v padded_secs "%02d" "$seconds"
bitrate=""; bitrate_padded="";
if [[ "$bitrate_check" == "Y" ]]; then
j=""
for i in `ffprobe "$newfile" 2>&1 | grep bitrate`; do
# Previous loop was the 'bitrate' label, so get bitrate now.
if [[ "$j" == 'bitrate:' ]]; then
bitrate="$i"
#printf -v bitrate_padded "%05d" "$bitrate"
fi
# Previous loop was the bitrate, so get the units now.
if [[ "$j" == "$bitrate" ]]; then
#bitrate="_""$bitrate_padded${i//\//p}"
bitrate="_""$bitrate${i//\//p}"
fi
j="$i"
done
fi
if [[ "$status" == 0 && -s "$newfile" ]]; then
mv -v "$newfile" "${basename}_${padded_mins}m${padded_secs}s${newfile//$ext/$bitrate$ext}"
else
echo "ERROR: ffmpeg exited with status $status, not renaming file."
fi
echo -e "\n * Finished in ${minutes}m${seconds}s! * \n"
done
done done
done done
done done done
done done done
## Finish ##
plural=""
if (( $count != 1 )); then
plural="s"
fi
echo "Completed tests after ${count} loop${plural}! :)"
}
# 20260914 - After playing with pv-test for a while.
function pv3 {
org="$1"
out="$2"
echo "Processing '$org' to '$out' using AV1 and OPUS."
## Versions ##
# v0
scale=-1:720
preset=0 # took 20 minutes where preset 2 was under 2 minutes
crf=18
vbr=2000k # this is creating 2Mbps files, not maxxing at 2.
overshoot=0
undershoot=100
# v1
preset=2 # WAY faster and still great.
crf=28 # much smaller filesize
# v2
# Try to mimic h264 better.
vbr=1000k
overshoot=100
# v3
# Fix weird aspect ratios.
scale="1280:720,setsar=1"
# v4
# Assuming it was just a weird Pixel phone video issue.
scale=-1:720
# Remove CRF since we are using VBR.
crf=""
# Still not 100% on these but seems like a good ballpark.
preset=6
vbr=800k
overshoot=50
undershoot=100
# Add audio bitrate.
abr=128k
# v5
# 800k had some visible degradation compared to pv. Up it a bit more.
vbr=1200k
preset=2
# v6
# 4 does way better than 2 or 6, at least on laptop, but phone and laptop
# scores have stayed very very similar. Also, overshoot of 100 is giving
# smaller files than less, and also allows more if needed, so keeping that.
preset=4
vbr=1200k
overshoot=100
undershoot=100
abr=128k
## Main ##
echo -e "\n * Original File * \n"
ffprobe -i "$org"
echo -e "\n * Starting Processing *\n"
date
set -x
ffmpeg -nostdin -hide_banner -loglevel level+warning \
-i "$org" \
-c:v libsvtav1 \
-preset $preset \
-filter:v scale=$scale \
-svtav1-params rc=1:tbr=${vbr}:overshoot-pct=${overshoot}:undershoot-pct=${undershoot} \
-c:a libopus \
-filter:a dynaudnorm=f=33:g=65:p=0.66:m=33.3 \
-b:a $abr \
-movflags +faststart \
"$out"
status="$?"
set +x
# -crf $crf \
if [[ "$status" != 0 || ! -s "$out" ]]; then
echo "Failed, deleting output."
mv -v "$out" ~/TRASH/
return $status
fi
echo -e "\n * Success! *"
}
# 20260915 - Stack 2 videos for comparing quality. TBD: Move to Ansible?
function vcompare {
vid1="$1"
vid2="$2"
if [[ -z $vid1 || -z $vid2 ]]; then
echo "ERROR: Missing vid1 ('$vid1') or vid2 ('$vid2'). "
return 1
fi
orientation="$3"
if [[ -z $orientation || ($orientation != "h" && $orientation != "v") ]]; then
echo -n "NOTICE: Received '$orientation' for orientation, using vertical instead. "
orientation="v"
echo "'$orientation'"
fi
mpv --lavfi-complex="[vid1][vid2]${orientation}stack[vo];[aid1][aid2]amix[ao]" \
"$vid1" \
--external-file="$vid2"
}
alias vcomp="vcompare "
### Web ### ### Web ###
@@ -867,9 +1364,9 @@ function git-check {
if [[ -d .git ]]; then if [[ -d .git ]]; then
git ls-remote --exit-code --heads origin dev git ls-remote --exit-code --heads origin dev
dev_exists="$?" dev_exists="$?"
if [[ "$dev_exists" == 0 ]]; then if [[ "$dev_exists" == 0 && "$dir" != *".wiki" ]]; then
git switch dev git switch dev
elif [[ "$dev_exists" == 2 ]]; then elif [[ "$dev_exists" == 2 || "$dir" == *".wiki" ]]; then
git switch main git switch main
else else
echo "ERROR: Unknown status for dev_exists, '$dev_exists'." echo "ERROR: Unknown status for dev_exists, '$dev_exists'."
@@ -908,8 +1405,441 @@ alias colors="check-colors"
alias term-colors="check-colors" alias term-colors="check-colors"
alias display-colors="check-colors" alias display-colors="check-colors"
### LLMs ###
## Finalize ## function ollama_stop() {
for model in `ollama ps | tail -n +2 | awk '{print $1}'`; do
echo "Stopping ${model}..."
ollama stop $model
done
}
alias ollama-stop="ollama_stop"
alias ollama-kill="ollama_stop"
alias ollama-killall="ollama_stop"
alias ollama-kill-all="ollama_stop"
alias ollama-stop-all="ollama_stop"
function ollama_models() {
for model in `ollama ls | grep -v NAME | awk '{print $1;}'`; do
echo $model
ollama show $model | grep -E "architecture|context length|quantization"
done
}
alias ollama-models="ollama_models "
alias ollama-show-models="ollama_models "
alias ollama-show="ollama_models "
alias ollama-dense="ollama_models "
alias ollama-moe="ollama_models "
alias show-models="ollama_models "
alias list-models="ollama_models "
function ollama_sizes() {
# VAR1 - Format. Choices are Markdown or Spaces.
typeset -l fmt="$1"
if [[ -z "$fmt" ]]; then
fmt=s
fi
if [[ "$fmt" != "s"* && "$fmt" != "m"* ]]; then
echo "ERROR: Format incorrect, choose Markdown or Spaces."
return 1
fi
sep=""
if [[ $fmt == "m"* ]]; then
sep="|"
fi
# VAR2 - Context
typeset -i num_ctx="$2"
context=""
if [[ -n $num_ctx ]]; then
context=',"options":{"num_ctx":'$num_ctx'}'
fi
# Column Formatting
col1=25
col2=12
col3=8
col4=12
spacing="$sep %-${col1}s $sep %${col2}s $sep %${col3}s $sep %${col4}s $sep"
#echo " Stopping all ollama usage..."
#sudo sv restart ollama >/dev/null 2>&1
#echo -e "\n Checking model disk and RAM sizes...\n"
printf "$spacing\n" "Model Name" "HDD (ls)" "Context" "RAM (ps)"
if [[ $fmt == "m"* ]]; then
printf "$spacing\n" ":------------------------" "-----------:" "-------:" "-----------:"
fi
for model in `ollama ls | grep -v NAME | awk '{print $1}'`; do
#ollama run $model "" --format json >/dev/null 2>&1
curl -s http://localhost:11434/api/generate \
-d '{"model":"'$model'","prompt":"","stream":false,"keep_alive":"1m"'$context'}' \
>/dev/null 2>&1
status=$?
hdd="`ollama ls | grep $model | awk '{print $3 $4}'`"
ram="`ollama ps | grep $model | awk '{print $3 $4}'`"
ctx="`ollama ps | grep $model | awk '{print $7}'`"
if [[ "$status" != 0 ]]; then
ram="TOO LARGE $ram"
ctx="FAIL $ctx"
sleep 10
fi
printf "$spacing\n" "$model" "$hdd" "$ctx" "$ram"
ollama stop $model >/dev/null 2>&1
while ollama ps | grep $model; do
sleep 1
done
done
#echo "Done!!"
}
alias ollama-sizes="ollama_sizes "
alias model-sizes="ollama_sizes "
alias model-memory="ollama_sizes "
alias model-mem="ollama_sizes "
function ollama_threads() {
# VAR1 - Model
model="$1"
if [[ -z $model ]]; then
model="qwen3.5:4b"
fi
# VAR2 - Context
typeset -i num_ctx="$2"
context=""
if [[ -n $num_ctx ]]; then
context=',"num_ctx":'$num_ctx''
fi
# Physical CPU Count (no longer using ansible_processor_vcpus, {{ ansible_processor_vcpus }})
# Will be something like 0-7, then get expanded to 0 1 2 3 4 5 6 7.
# Runnning with 0 causes default behavior, 1 per physical core, 8!
cores=$(cat /sys/devices/cpu_core/cpus | tr ',' '\n' | sed 's/-/ /' | xargs -L1 seq)
# Flatten the output (trims newlines and extra spacing).
cores=$(echo $cores)
# Take out useless tests. 1 CPU is silly. If we have 8 physical then
# only need to look at 4, 6, 7, and 8 (which is done by 0/default).
cores=${cores/ 1 / }
if [[ "$cores" == *" 7" ]]; then
cores=${cores/ 2 / }
cores=${cores/ 3 / }
cores=${cores/ 5 / }
fi
# Do the 0 test last.
cores="${cores/0 / } 0"
#echo " Stopping all ollama usage..."
#sudo sv restart ollama >/dev/null 2>&1
# Benchmark Thread Count
for t in $cores; do
start=$SECONDS
echo -n "`date` - $model w/ $t Thread(s): "
speed=$(curl -s http://localhost:11434/api/generate \
-d '{"model":"'$model'","prompt":"Hello","stream":false,"keep_alive":"1m","options":{"num_thread":'$t$context'}}' \
| jq '.eval_count * 1000000000 / .eval_duration'
)
finish=$SECONDS
ctx="`ollama ps | grep $model | awk '{print $7}'`"
time=$(( $finish - $start ))
#echo "tokens/sec: $speed @ context=$ctx, time: $time secs"
printf "%-32s %18s %16s\n" "tokens/sec: $speed" "@ context=$ctx," "time: $time secs"
ollama stop $model >/dev/null 2>&1
done
}
alias ollama-threads="ollama_threads "
alias ollama-cpus="ollama_threads "
alias ollama-cpu="ollama_threads "
function ollama_benchmark_usage() {
cat <<- EOF
USAGE: ollama-benchmark CONTEXTS [THREADS] [IGPUS] [MODELS] [-h | --help]
Tests installed models at a certain context, thread count, and iGPU setting.
PARAMETERS
CONTEXTS
Sent as num_ctx to ollama. No default.
THREADS
Sent as num_threads to ollama. Defaults to 0.
IGPUS
Values to set OLLAMA_IGPU_ENABLE to. Defaults to 1.
MODELS
Model names to test. Defaults to all of 'ollama ls'.
EXAMPLES:
Test models with at a context of 32000, default threads, and iGPU enabled.
ollama-benchmark 32000 0 1
Test qwen3.5:4b with at a context of 128k, 4 threads, and iGPU disabled.
ollama-benchmark 128000 4 0 qwen3.5:4b
Variables can also be specified through variables:
context=64000 threads=7 igpu=0 ollama-benchmark
context=64000 threads=7 ollama-benchmark
context=64000 igpu=0 ollama-benchmark
context=64000 model=qwen3.5:4b ollama-benchmark
The parameters can also act as arrays to cause extra looping.
ollama-benchmark "32000 64000 128000 256000" "4 7 0" "0 1" \
"qwen3.8:27b qwen3.6:35b qwen3.6:27b qwen3.5:35b qwen3.5:27b"
Aliases:
ollama-test
EOF
}
function ollama_benchmark() {
#############################################################################
# Parameters
#############################################################################
if [[ "$@" == *"-h"* || "$@" == *"help"* ]]; then
ollama_benchmark_usage
return 0
fi
contexts="${1:-$contexts}"
if [[ -z "$contexts" ]]; then
echo " ERROR: Context is required."
ollama_benchmark_usage
return 1
fi
threads="${2:-$threads}"
if [[ -z $threads ]]; then
threads=0
fi
igpus="${3:-$igpus}"
if [[ -z "$igpus" ]] ; then
igpus=1
fi
models="${4:-$models}"
if [[ -z "$models" ]]; then
models="`ollama ls | grep -v NAME | awk '{print $1}'`"
fi
DEBUG="${DEBUG}"
QUIET="${QUIET}"
[[ -z "$QUIET" ]] && echo -e "\n Sharing run parameters..."
[[ -z "$QUIET" ]] && cat <<- EOF
DEBUG=$DEBUG
QUIET=$QUIET
contexts=$contexts
threads=$threads
igpus=$igpus
models=$models
EOF
[[ -z "$QUIET" ]] && echo " Done!"
#############################################################################
# Variables
#############################################################################
col_mdl=25
col_hdd=6
col_ctx=8
col_ram=6
col_thr=7
col_gpu=4
col_cpu=9
col_spd=11 col_spd_round=2
col_tim=8
log_file="ollama_benchmark.log.txt"
[[ -z "$QUIET" ]] && echo -e "\n Logging ollama to '$log_file'..."
declare champ_{s,t}_{mdl,num,ctx,thr}
#############################################################################
# Functions
#############################################################################
function wait_for_ollama() {
while ! ollama ps >/dev/null 2>&1; do
sleep 1
done
}
#############################################################################
# Main
#############################################################################
if [[ ! -d /sdcard && -d /etc/sv ]]; then
[[ -z "$QUIET" ]] && echo -e "\n Stopping ollama runit service..."
sudo sv disable ollama >/dev/null 2>&1
sudo sv stop ollama >/dev/null 2>&1
sleep 5
[[ -z "$QUIET" ]] && echo " Done!"
fi
[[ -z "$QUIET" ]] && echo -e "\n Starting main loop... \n"
declare GRY="`tput setaf 8`" WHT="`tput setaf 7`" RST="`tput sgr0`"
printf "$WHT| %-${col_mdl}s | %${col_hdd}s | %${col_ctx}s | %${col_ram}s | %${col_thr}s | %${col_gpu}s | %${col_cpu}s | %${col_spd}s | %${col_tim}s |\n" \
"Model" "HDD" "Context" "RAM" "Threads" "iGPU" "Processor" "Speed (t/s)" "Time (s)"
printf "| %-${col_mdl}s | %${col_hdd}s | %${col_ctx}s | %${col_ram}s | %${col_thr}s | %${col_gpu}s | %${col_cpu}s | %${col_spd}s | %${col_tim}s |$RST\n" \
":------------------------" "-----:" "-------:" "-----:" "------:" "---:" "--------:" "----------:" "-------:"
declare last_igpu="" count=0
unset model context thread igpu
for model in $models; do
for context in $contexts; do
for thread in $threads; do
for igpu in $igpus; do
if [[ -z "$last_igpu" || "$last_igpu" != "$igpu" ]]; then
killall ollama >/dev/null 2>&1
sleep 5
export OLLAMA_IGPU_ENABLE=$igpu
export OLLAMA_VULKAN=$igpu
(ollama serve >$log_file 2>&1 &)
wait_for_ollama
sleep 5
fi
last_igpu="$igpu"
declare CLR="$WHT"
if (( count % 2 == 1 )); then
CLR="$GRY"
fi
(( count++ ))
hdd="`ollama ls | grep $model | awk '{print $3 $4}'`"
printf "$CLR| %-${col_mdl}s | %${col_hdd}s | " "$model" "$hdd"
# Start the model and store the response.
start=$SECONDS
speed_json=$(curl -s http://localhost:11434/api/generate \
-d '{"model":"'$model'","prompt":"Hello","stream":false,"keep_alive":"1m","options":{"num_ctx":'$context',"num_thread":'$thread'}}' \
2>/dev/null
)
status_ollama=$?
finish=$SECONDS
[[ -n "$DEBUG" ]] && echo "DEBUG: status_ollama=$status_ollama"
time=$(( $finish - $start ))
# Calculate the values if we got a successful response.
declare ram cpu ctx speed status_jq=0
if [[ "$status_ollama" == 0 ]]; then
speed=$(echo "$speed_json" | jq '.eval_count * 1000000000 / .eval_duration' 2>/dev/null)
status_jq=$?
[[ -n "$DEBUG" ]] && echo "DEBUG: status_jq=$status_jq"
if [[ "$status_jq" != 0 ]]; then
speed=0
fi
else
[[ -n "$DEBUG" ]] && echo "DEBUG: Using failed values. (ollama)"
ctx="OLLAMA"
ram="DIED"
cpu="FAIL"
speed=0
killall ollama
(ollama serve >>$log_file 2>&1 &)
wait_for_ollama
fi
if [[ "$status_jq" != 0 ]]; then
[[ -n "$DEBUG" ]] && echo "DEBUG: Using failed values. (jq)"
ctx="RESPONSE"
ram="MLFRMD"
cpu="FAIL"
speed=0
fi
if [[ "$status_jq" == 0 && "$status_jq" == 0 ]]; then
[[ -n "$DEBUG" ]] && echo "DEBUG: Using successful values."
ram="`ollama ps | grep $model | awk '{print $3 $4}'`"
cpu="`ollama ps | grep $model | awk '{print $5 $6}'`"
ctx="`ollama ps | grep $model | awk '{print $7}'`"
[[ -n "$DEBUG" ]] && echo "DEBUG: champ_s_num=$champ_s_num, speed=$speed"
if [[ -z "$champ_s_num" ]] \
|| awk -v a="$speed" -v b="$champ_s_num" 'BEGIN { exit !(a > b) }'
then
[[ -n "$DEBUG" ]] && echo "DEBUG: New speed champ!"
champ_s_num="$speed"
champ_s_mdl="$model"
champ_s_ctx="$ctx"
champ_s_thr="$thread"
fi
[[ -n "$DEBUG" ]] && echo "DEBUG: champ_t_num=$champ_t_num, time=$time"
if [[ -z "$champ_t_num" ]] \
|| awk -v a="$time" -v b="$champ_t_num" 'BEGIN { exit !(a < b) }'
then
[[ -n "$DEBUG" ]] && echo "DEBUG: New time champ!"
champ_t_num="$time"
champ_t_mdl="$model"
champ_t_ctx="$ctx"
champ_t_thr="$thread"
fi
fi
printf "%${col_ctx}s | %${col_ram}s | %${col_thr}s | %${col_gpu}s | %${col_cpu}s | %${col_spd}.${col_spd_round}f | %${col_tim}s |$RST\n" \
"$ctx" "$ram" "$thread" "$igpu" "$cpu" "$speed" "$time"
ollama stop $model >/dev/null 2>&1
while ollama ps | grep "$model"; do
[[ -n "DEBUG" ]] && echo "DEBUG: Waiting for model to finish..."
sleep 1
done
done
done
done
done
echo -e "\n Done!! :D \n"
cat <<- EOF
Speed Champion: $champ_s_mdl at ${champ_s_thr}-$champ_s_ctx with a tokens/second of ${champ_s_num}!
Time Champion: $champ_t_mdl at ${champ_t_thr}-$champ_t_ctx with a time of ${champ_t_num}!
EOF
#############################################################################
# Finish
#############################################################################
[[ -z "$QUIET" ]] && echo -e "\n Killing local ollama serve..."
killall ollama
[[ -z "$QUIET" ]] && echo " Done!"
if [[ ! -d /sdcard && -d /etc/sv ]]; then
[[ -z "$QUIET" ]] && echo -e "\n Restarting runit service..."
sudo sv enable ollama >/dev/null 2>&1
sudo sv start ollama >/dev/null 2>&1
[[ -z "$QUIET" ]] && echo " Done!"
fi
[[ -z "$QUIET" ]] && echo -e "\n Done!!! :)"
}
alias ollama-benchmark="ollama_benchmark "
alias ollama-test="ollama_benchmark "
### Finalize ###
# Export all functions! # # Export all functions! #
eval "$(declare -F | grep -v _ | sed 's/-f /-fx /')" eval "$(declare -F | grep -v _ | sed 's/-f /-fx /')"