venerdì 17 gennaio 2025

Pandas su serie tempo

Problema: hai un csv che riporta una serie tempo datetime/valore di un sensore

Effettuare calcoli, ordina le righe, ricampiona il passo temporale, colma i buchi della serie tempo con interpolazione in modo semplice

Data;Valore_p
2024-07-24 12:42:05;0
2024-07-24 12:44:05;0
2024-07-24 12:46:05;0

 soluzione : usa Pandas di Python

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import argrelextrema


#legge i dati dal csv
df_b = pd.read_csv('battente.csv', sep=';',header=0, parse_dates = ['Data'], date_format = '%Y-%m-%d %H:%M:%S')
#ricampiona i dati con un dato al giorno usando il valore medio
df_b_res = df_b.resample('1h', on='Data').mean()
#df_b.iloc[:,1] = df_b.iloc[:,1].apply(lambda x: (x-x.mean())/ x.std())
print(df_b)



df_p = pd.read_csv('pluviometro.csv', sep=';',header=0, parse_dates = ['Data'], date_format = '%Y-%m-%d %H:%M:%S')
#df_p = df_p.shift(periods=3)
df_p_res = df_p.resample('1h', on='Data').mean()

#unisce i due file usando come chiave la colonna temporale
merged_dataframe = pd.merge_asof(df_p_res, df_b_res, on="Data")
#rimuove le righe in cui non ci sono valori
df_finale = merged_dataframe.dropna(how='any')


#cerca i massimi locali facendo scorrere una finestra di 12 ore
df_finale['local_max_p'] = df_finale.iloc[argrelextrema(df_finale.Valore_p.values, np.greater_equal,order=12)[0]]['Valore_p']
df_finale['local_max_b'] = df_finale.iloc[argrelextrema(df_finale.Valore_b.values, np.greater_equal,order=12)[0]]['Valore_b']

#elimina i massimi locali che sono sotto ad una soglia
df_finale['local_max_p'] = np.where(df_finale["local_max_p"] < 1.0,np.nan,df_finale["local_max_p"])
df_finale['local_max_b'] = np.where(df_finale["local_max_b"] < 1.0,np.nan,df_finale["local_max_b"])

df_finale.to_csv("allineato.csv", sep=";")


fig, ax1 = plt.subplots()
# Plot first time series on the primary axis
ax1.plot(df_finale['Data'], df_finale['Valore_b'], 'g-')
ax1.plot(df_finale['Data'], df_finale['local_max_b'], 'mo')

ax1.set_xlabel('Data')
ax1.set_ylabel('Battente (m)', color='g')
ax2 = ax1.twinx()
ax2.plot(df_finale['Data'], df_finale['Valore_p'], 'b-')
ax2.plot(df_finale['Data'], df_finale['local_max_p'], 'ro')

ax2.set_ylabel('Prec.(mm)', color='b')
plt.savefig('grafico.png')
plt.show()






martedì 14 gennaio 2025

Cheshire Cat Ai

Cheshire Ai e' un progetto italiano che sta crescendo adesso


Per provarlo si clona il progetto 

git  clone https://github.com/cheshire-cat-ai/local-cat.git

su un x86 si puo' usare il file compose.yml per avere una installazione di Ollama, Cheshire AI e QDrant

Se non si ha una GPU NVidia si devono commentare le ultime righe

#    deploy:
#      resources:
#        reservations:
#          devices:
#            - driver: nvidia
#              count: all
#              capabilities: [ gpu ]

 

Su Mac invece conviene installare la app nativa di Ollama per M1 in modo da sfruttare la accelerazione Metal e si usa il file docker-compose-mac.yaml che crea un docker di Cheshire AI e QDrant

Per creare su x86 si usa

docker compose up -d

e poi si installano sul docker i modelli (in questo caso mistral)

docker exec ollama_cat ollama pull mistral:7b-instruct-q2_K

Per interagire con Chershire si punta a 


http://localhost:1865/admin/

https://localhost:1865/public

Si deve configurare il language model in Cheshire


altrimenti nel caso di Apple, dove il server Ollama e' esterno al docker si usa l'indirizzo http://host.docker.internal:11434



Usando questo esempio https://cheshirecat.ai/local-embedder-with-fastembed/ si configura l'embedder usando quello interno in modo da girare tutto in locale


Per addestrare il modello tramite RAG e' sufficiente trascinare in PDF sull'interfaccia ed attendere il processamento




Llama.cpp Linux ed Apple

Su Linux la cosa piu' comoda e' scaricare i sorgenti da https://github.com/ggerganov/llama.cpp e compilando


mkdir build 

cd build
make
sudo make install
sudo ldconfig

Su Mac si puo' semplicemente brew install llama.cpp

a questo punto si devono scaricare i modelli in formato GGUF come per esempio

https://huggingface.co/bullerwins/Meta-Llama-3.1-8B-Instruct-GGUF

che pesa circa 4.47 Gb (per confronto gli altri modelli pesanno 2b = 3G 16b = 15Gb)

altrimenti si puo' usare il modello 3.2 (3.42 Gb)

https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF?show_file_info=Llama-3.2-3B-Instruct-Q8_0.gguf

I file GGUF devono copiati nel folder models

Per interagire 

llama-cli -m models/Meta-Llama-3.1-8B-Instruct-Q4_K_S.gguf -p "You are a helpful assistant" --conversation 

llama-cli -m ./models/Llama-3.2-3B-Instruct-Q8_0.gguf -p "You are a helpful assistant" --conversation

Altrimenti per attivare LLama.cpp e scaricare in automatico il modello si usa

llama-cli \                

  --hf-repo "bullerwins/Meta-Llama-3.1-8B-Instruct-GGUF" \

  --hf-file Meta-Llama-3.1-8B-Instruct-Q2_K.gguf \

  -p "You are a helpful assistant" \

  --conversation

Oltre alla modalita' di shell puo' essere attivata la modalita' server 

Usando Homebrew su Mac si puo'usare 

llama-server \

  --hf-repo "bullerwins/Meta-Llama-3.1-8B-Instruct-GGUF" \

  --hf-file Meta-Llama-3.1-8B-Instruct-Q2_K.gguf 



Si punta quindi su http://localhost:8080



venerdì 3 gennaio 2025

Change Detection with structural similarity

L'idea di base e' quella di cercare le differenze tra le due immagini sottostanti

Non e' immediatamente visibile ma ci sono dei sassi che si sono spostati nella zona a coordinata 2600,1600 circa. Per questa prova e' stato impiegato l'algoritmo di Structural Similarity  di SkImage

Foto 1

 

Foto2
il calcolo indica un indice di somiglianza di circa il 71%

 



 Questa e' l'elaborazione (bianco minima differenza)

 


 

Il risultato finale e' la vegetazione con il suo movimento ha completamente obliterato il segnale relativo allo spostamento dei sassi

from skimage.metrics import structural_similarity
import cv2
import numpy as np

# Load images
before = cv2.imread('20241114.jpg')
after = cv2.imread('20241115.jpg')

# Convert images to grayscale
before_gray = cv2.cvtColor(before, cv2.COLOR_BGR2GRAY)
after_gray = cv2.cvtColor(after, cv2.COLOR_BGR2GRAY)

# Compute SSIM between the two images
(score, diff) = structural_similarity(before_gray, after_gray, full=True)
print("Image Similarity: {:.4f}%".format(score * 100))

# The diff image contains the actual image differences between the two images
# and is represented as a floating point data type in the range [0,1]
# so we must convert the array to 8-bit unsigned integers in the range
# [0,255] before we can use it with OpenCV
diff = (diff * 255).astype("uint8")
diff_box = cv2.merge([diff, diff, diff])

# Threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
thresh = cv2.threshold(diff, 20, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

mask = np.zeros(before.shape, dtype='uint8')
filled_after = after.copy()

for c in contours:
area = cv2.contourArea(c)
if area > 40:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(before, (x, y), (x + w, y + h), (36,255,12), 2)
cv2.rectangle(after, (x, y), (x + w, y + h), (36,255,12), 2)
cv2.rectangle(diff_box, (x, y), (x + w, y + h), (36,255,12), 2)
cv2.drawContours(mask, [c], 0, (255,255,255), -1)
cv2.drawContours(filled_after, [c], 0, (0,255,0), -1)

cv2.imshow('20241114', before)
cv2.imshow('20241115', after)
cv2.imshow('diff', diff)
cv2.imshow('diff_box', diff_box)
cv2.imshow('mask', mask)
cv2.imshow('filled after', filled_after)
cv2.waitKey()

 

giovedì 2 gennaio 2025

LLama download checkpoint

Oltre a scaricare i dati per usare un modello puo' essere necessario effettuare un retrain di un modello ed in questo caso non si possono usare i modelli quantizzati ma i dati relativi ad checkpoint


 

per per fare cio' si usa llama-stack

Si deve pero' prima richiesta su  https://www.llama.com/llama-downloads/

e si ottiene una con un link

si installa poi llama-stack

pip install llama-stack
llama model list

llama download --source meta --model-id meta-llama/Llama-3.2-3B 

viene richiesto a questo punto di incollare il link giusto per mail

i file del checkpoint si trovano in .llama

luca@Dell:~$ cd .llama/
luca@Dell:~/.llama$ ls
checkpoints
luca@Dell:~/.llama$ cd checkpoints/
luca@Dell:~/.llama/checkpoints$ ls -la
total 12
drwxr-xr-x 3 luca luca 4096 Dec 31 06:24 .
drwxr-xr-x 3 luca luca 4096 Dec 30 17:30 ..
drwxr-xr-x 2 luca luca 4096 Dec 30 17:31 Llama3.2-3B
luca@Dell:~/.llama/checkpoints$ cd Llama3.2-3B/
luca@Dell:~/.llama/checkpoints/Llama3.2-3B$ ls
checklist.chk  consolidated.00.pth  params.json  tokenizer.model
luca@Dell:~/.llama/checkpoints/Llama3.2-3B$ ls -la
total 6277140
drwxr-xr-x 2 luca luca       4096 Dec 30 17:31 .
drwxr-xr-x 3 luca luca       4096 Dec 31 06:24 ..
-rw-r--r-- 1 luca luca        156 Dec 30 17:31 checklist.chk
-rw-r--r-- 1 luca luca 6425581594 Dec 30 17:36 consolidated.00.pth
-rw-r--r-- 1 luca luca        220 Dec 30 17:31 params.json
-rw-r--r-- 1 luca luca    2183982 Dec 30 17:31 tokenizer.model
luca@Dell:~/.llama/checkpoints/Llama3.2-3B$


Casio SA-38

Ho trovato vicino ad un cassonetto una tastiera SA-38 molto simile a quello che usavo da ragazzo...era in condizioni pessime, molto sporca piu' che altro perche' la gommapiuma della custodia con il tempo si e' polverizzata (nel senso reale della parola) ed e' entrata in ogni pertugio

Troppo curioso di vedere come e' fatta dentro

Aprendo alcuni supporti di plastica delle viti si sono distrutti (non so se qualcuno prima di me la aveva aperta)...inoltre era chiara una perdita di acido nel vano batterie e la corrosione aveva distaccato il cavo del positivo

Dal punto di vista dell'elettronica ci sono veramente pochi componenti ..e' praticamente un SOC (system on a chip) con un AN8053 che funge da regolatore di tensione ed amplificato

AN8053 con jack output audio ed VIN 7.5 V

 

Un MSM6387 in cui sono inseriti tutti i suoni in PCM, un ADC e la gestione degli input dai tasti. La CPU genera una onda a gradini che viene poi smussata da un filtro esterno


MSM6387-11


Su una daughter board piuttosto posticcia c'e' il cristallo oscillatore a 21.725 MHz


I dati di fabbrica indicano una fabbrica in Agosto 1992



tutto e' montato su due schede con connettori saldati (non e' stata pensata per essere smontata e riparata)



i pulsanti sono del tipo presenti in alcune vecchie calcolatrici o tastiere PC con una membrana di gomma che racchiude al suo interno la parte conduttiva


i tasti vengono riconosciuti da una matrice



lunedì 30 dicembre 2024

Ollama e Jetson Nano 4G

Ancora nel tentativo di utilizzare in modo serio la Jetson Nano ho provato ad usarla per Ollama seguendo le istruzioni da https://dev.to/ajeetraina/running-ollama-2-on-nvidia-jetson-nano-with-gpu-using-docker-hfi (e' stato usato il docker perche' usando lo script di installazione dal sito di Ollama fallisce per la necessita' di capabilitie maggiore di quella disponibile da Jetson Nano)

Per creare il docker si seguono i comandi

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
    | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
    | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
    | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update


sudo apt-get install -y nvidia-container-toolkit


sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker


sudo docker run -d --gpus=all --runtime nvidia -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

sudo docker exec -it ollama ollama run llama2


Alcune persone su Github si lamentano che il docker non sfrutti la GPU della Jetson ma installando il comando jtop (tramite  sudo pip3 install -U jetson-stats) si vede che il carico sulla GPU non e' a zero

schermata di jtop

Per vedere se ollama e' in fuzione basta bussare alla porta 11434



La mia Jetson ha una ram di 4Gb ma solo pochi modelli sono in grado di girare (a meno di non quantizzarli)

Funzionano i seguenti modelli

tinyllama

llama3.2:1b

starcoder:1b 

Non funzionano invece  

orca-mini:3b (ncessita 5.1 GiB di ram )

mistral-small (necessita 14.4 Gib)

llama3.2


Per interagire si puo' installare web ui (che e' in generale decisamente piu' lenta della linea di comando) tramite il docker


docker run -d -p 3000:8080 --runtime=nvidia --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui2 --restart always ghcr.io/open-webui/open-webui:cuda


docker run -d -p 3000:8080 --gpus all --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:cuda



L'unico aspetto veramente positivo di Jetson nano e' il consumo massimo di 5W



comunque a questo semplice prompt l'AI TinyLLama ha fatto una serie veramente sanguionosa di errori

>>> raccontami la storia di Albert Einstein

Einstein, uno dei più grandi pensatori e fisici del XX secolo, nacque nel 1879 a Ulm, in Germania. La sua infanzia fu caratterizzata da una forte intesa con gli  elementi naturali e una grande affinità per la matematica.Nel 1890 Einstein iniziò le sue scuole medie a Kiel e Karlsruhe, dove cominciò a studiare fisica e matematica. Nel 1896 si unì al Liceo Max Planck di Göttingene, dove incontrò il suo futuro compagno di insegnamento, Max Planck.Einstein studiò filosofia, letteratura e lingue, ma la sua vera passione era la fisica. Durante i suoi primi anni universitari, si avvicinò alla teoria della relatività Speciala di Albert Michelson e George Gamow, che cercavano di spiegare l'effetto fotoelettrico.Nel 1905 Einstein pubblicò i suoi esperimenti sull'effetto elettronico, che dimostrarono la connessione tra le onde e le particelle. Questa scoperta lo aprì alla teoria della relatività generale di Albert Einstein, sviluppata dopo il 1905. Nel 1914 Einstein si unì al corpo terrestre militare tedesco durante la Prima Guerra Mondiale e fu catturato dai soldati austriaci. Durante l'arresto Einstein scrisse la sua famosa lettera a Max Planck, in cui chiese di essere reso responsabile per il tempo di vita che aveva trascorso nella prigione. Nel 1919 Einstein ricevette la medaglia Nobel per la fisica per la sua teoria della relatività generale. Tuttavia, ricevette anche una serie di minacce e messaggi oscure, tra cui un'ultima minaccia che lo costringe a lasciare l'Austria nel 1933.Durante il regime nazista, Einstein si ritirò in Svizzera, dove continuò a studiare fisica. Nel 1932 ricevette la medaglia Copley per la sua carriera accademica. Tuttavia, si unì all'Ordine di Malta nel 1933 e fu invitato a lasciare gli Stati Uniti. Nel 1935 Einstein pubblicò il suo libro "La relatività generale", che divenne un successo internazionale. Tuttavia, ricevette sempre più minacce e messaggi oscari, e nel 1938 scrisse la sua famosa formula dell'Einstein-Rosen bridge. Durante l'Anno di Natale 1939 Einstein fu attaccato con una bomba atomica a Praga, in Cecoslovacchia. La sua salute si deteriorò ulteriormente negli anni successivi e morì il 18 April 1955 a Princeton, nel New Jersey. Einstein lasciò un'impronta indelebile sulla scienza e nella cultura, e la sua teoria della relatività generale rimane una delle fondamenta fondazionali dell'attuale fisica. La sua storia è un esempio di come la curiosità, l'iniziativa e la determinazione possano portare a grandi risultati scientifici.





Pandas su serie tempo

Problema: hai un csv che riporta una serie tempo datetime/valore di un sensore Effettuare calcoli, ordina le righe, ricampiona il passo temp...