ラズパイ5のドライブをSSDにする

そこそこSDカードの中身も落ち着いてきて、サイズも20GB/64GBぐらいになってきたので、運用寿命と速度を勘案してSSDにしました

仕様は写真から読み取れますが、アダプタボードとNVMe仕様のSSD、サイズは256GBでおそらく一生持ちそう

ディスクの作成は、SD Card Copierを使って行いました、

New Partition UUIDsにチェックは重要、チェックしないと完全クローンになるので、SDカードとSSD同時実装時に区別つきません

最初、チェックしないでコピーしたのでリカバリに苦労、以下LLMに聞きながら実行した手順、要は「MBR/GPTヘッダ完全削除
」をしないとダメのようです

同じUUIDでコピーした時のリカバリ手段、macで単純ディスク消去だと
MBR/GPTヘッダが残ってるらしく不完全な初期化です

$ diskutil list # SSDのドライブ番号を検索する(/dev/disk4 だった)
$ diskutil unmountDisk /dev/disk4	# 外付けSSD番号を指定
# MBR/GPTヘッダ完全削除
(初期化するからディスク名や形式は重要ではないはず)
$ diskutil eraseDisk JHFS+ NewDiskName /dev/disk4
$ sudo dd if=/dev/zero of=/dev/disk4 bs=1M count=100

インストールして、bootデバイスを探す時間は無駄なのでSSDを一番最初にアクセスするような設定に変更します

$ sudo rpi-eeprom-config --edit
 ファイルの461 -> 416に変更(右から順番に探して、6はSSDです)

$dfの結果はこんな感じ、

電源オン起動時間は体感でも明らかに早いし、アプリ(例えばブラウザ)の起動も早い、VNCでダミーHDMI入れてないから、相変わらずフレームレートは出ないけども

P.S. デスクアクセス性能

以前SDカードの値があったので比較してみる

$ sudo curl https://raw.githubusercontent.com/TheRemote/PiBenchmarks/master/Storage.sh | sudo bash


     Category                  Test                      Result     
HDParm                    Disk Read                 90.82 MB/sec             
HDParm                    Cached Disk Read          90.94 MB/sec             
DD                        Disk Write                32.5 MB/s                
FIO                       4k random read            6317 IOPS (25268 KB/s)   
FIO                       4k random write           845 IOPS (3382 KB/s)     
IOZone                    4k read                   29989 KB/s               
IOZone                    4k write                  3288 KB/s                
IOZone                    4k random read            30032 KB/s               
IOZone                    4k random write           3268 KB/s                

                          Score: 2530                             


     Category                  Test                      Result     
HDParm                    Disk Read                 441.07 MB/sec            
HDParm                    Cached Disk Read          432.23 MB/sec            
DD                        Disk Write                345 MB/s                 
FIO                       4k random read            87521 IOPS (350085 KB/s) 
FIO                       4k random write           85333 IOPS (341333 KB/s) 
IOZone                    4k read                   132985 KB/s              
IOZone                    4k write                  169992 KB/s              
IOZone                    4k random read            63871 KB/s               
IOZone                    4k random write           181370 KB/s              

                          Score: 39288                                       

今時のベンチマークに比較して、めちゃくちゃ早いわけではないが、妥当な値と言えるだろう

 

admin

gemma3は優れものだね

今月公開されたようですが、Googleのgemma3は4bぐらいだと普通に回答のレベルも高いから、応答時間含めて実用レベルです

1b/4b・・・とありますが、実は1bだとラズパイ5でも普通に動いた、swapは起きてますが

モデルサイズも1G以下でコンパクト、

但しMacで動かした4bと比較すると精度は違う、以下は1bのレスポンス

4bだと、

と言う感じですから、差は明らか

次にDifyでモデルを、以下を参考にGeminiからollamaに変えてみた

https://note.com/dify_lab/n/n09e680c825cf

Difyからの接続設定

使えるモデルは、以下のように二つになります

どちらを使うかは、モデルのところをクリックしてこれはollmaに変えた後、

メモリ使用量もそれほどでもない、

と言うことで、gemma3は期待に違わずよく出来てます、

 

admin

M1 vs M4の性能比較(非常に限定的な場合で)

M1 MacBook AirとM4 MacBook Pro 14inchの性能差ということですが、以下のリンクは素数計算をPerplexityでRustコード発生させて実行した時のもの

https://isehara-3lv.sakura.ne.jp/blog/2024/10/23/生成a-igeminiでコード生成rust/

<Geminiで生成したシングルスレッド版 : release mode>
2から1000000までの素数:
Elapsed time: 37.51125ms

<Geminiで生成したマルチスレッド版 : release mode>
2から1000000までの素数:
Elapsed time: 7.397958ms

以上はM1 MacBook Airでの結果


M4 MacBook Proで実行してみると(実行ごとにばらつくから5回実行してベストタイム)

<シングルスレッド版>
2から1000000までの素数:
Elapsed time: 27.473ms(1.36倍)

<マルチスレッド版>
2から1000000までの素数:
Elapsed time: 6.449875ms(1.15倍)

シングルスレッド(マルチコア対応)はそんなものかと思うけど、マルチコア対応のコードの実行速度はイマイチ、考えられる可能性は計算量に比較してオーバーヘッドが大きいせいじゃ無いかと思う

FusionやiMovieなどの立ち上げや書き出しは、はっきりわかるほどの差があるからね、非常に限定的なアプリではありますが、体感ではシングルスレッドの時の速度差ということになります、自分の使い方ではCPU速度よりもメモリとSSDの絶対量確保の方が重要

 

admin

M4 MacBook Pro 14ファーストインプ

M1 MacBook Airのリソース不足(メモリ16GB/SSD 512GB)で買い換えたM4 MacBook Pro 14(メモリ32GBにアップ、SSDは1TB、キーボードはUSモデル)が昨日到着したのでその感想、購入している間にM4 MacBook Airも発表されましたが、まあ欲しい時に買うのがベスト

個人的にAirに比較したProのアドバンテージは、

① Youtubeで音楽流してもスピーカーの音はかなりまとも、Airは音がしょぼい

② 拡張性:Appleの微妙なヒエラルキーでもありますが、HDMIとSDカードスロットはポートレプリケータなくても外出先で使えるのは便利

③ LCD表示品質:Airのような表示のケバケバしさはなくて自然な色合いと感じます、狭ベゼルでもあるのでスペースも有効活用

M4 Pro以上のチップは値段と性能のバランスから考えたら無い選択、使い方からしてもM4で良いかな

<移行>

同じApple siliconなのでM1 MacBook Airからそのままデータ移行、メールアカウントやアプリの認証だけは再設定必要

バックアップ(timemachine)はAirを引き継いでそのまま何の設定もなしにできた、ただしAirの最終状態からの差分ではなくてAirを初回にバックアップしてからの差分をバックアップしたようです

<使用感>

① ブラウザ(Safari, Chorme)、VScode、コンテナ(Podman, Rancher Desktop)立ち上げた状態で、LLM(ollamaの80億モデル)動かした時にメモリ使用量は26GBぐらいで頭打ち、M1 Macではかなりスワップが発生してイエローマークだったけど、今のところ32GBあれば何とかなる

② 速度的にはアプリの立ち上げは高速化されている、特にAutodesk Fusionなどを立ち上げるとよくわかる

③ キーボードのタッチ感(音)が説明は難しいけど微妙に異なるんだよね、箱(筐体)が違うせいかも知れない

④ 電池の充電をきっちり80%で打ち切るような設定になっている、M1 Macまでは充電抑止ロジックがよく分からなかったけれど

⑤ M4からでも無いだろうけど、IPhone15は既に切り替わり、ACアダプタのケーブルが柔軟性があるものに変わっているいるから取り回しが楽になっているのとMagSafeは安全面からもおすすめだと思う

普通にM1 Macの資源引き継いで使えるというありきたりの感想、まだファンは一度も回ってないから、ファンが付いていることすら気づいてない

 

admin

ローカルマシンでLLMを使ってみる

軽量のプラットホームであれば、パソコンでも動作可能とのことなので、M1 Mac(16GB)でポピュラーと思われるOllamaを動かしてみました、メモリは16GBはないと動きません、遅くても良いからとラズパイ5(8GB)で動かそうとしたらメモリ不足で動きませんでした

インスト方法は、モデルの変換も記述されています

https://qiita.com/s3kzk/items/3cebb8d306fb46cabe9f

OllamaはLLMのフレームワークなので実際に使うためにはモデルのインストが必要になります

<コマンドラインでのやり取りの例>

起動方法は、

% ollama run elyza:jp8b

一方APIを使う場合には、

% ollama serve 

でollamaを起動しておいて、

https://highreso.jp/edgehub/machinelearning/ollamapython.html

を参考にスクリプトを作成して、

import requests
import json

url = 'http://localhost:11434/api/chat'

data = {
    "model":"elyza:jp8b",
    "messages": [
        {
            "role": "user",
            "content": "千葉県の名産品を教えて、"
        }
    ],
    "stream": False
}

response = requests.post(url, data=json.dumps(data))
response_data = response.json()
print(response_data)

このスクリプトを実行すると、

のようなjson形式のレスポンスが返ってきます、コンソールの対話モードに比較するとMacが考えている時間がかなり長い、おそらく10秒ちょっとかな、

リソースの消費状況は、

 

こんな感じなので、やはりラズパイ5では実用上は無理かな、

 

admin

 

能登地震の波形のスペクトルを求めてみた

正弦波の合成だけでは実用性はないので、今年の元旦の能登地震の公開されている波形データからスペクトルを求めてみた

公開先はこちらですが、トップにある輪島市のデータを使っています、形式はcsvなのでヘッダー情報除けばPythonやRustで簡単に処理できます

・ヘッダー情報

SITE CODE= 67016輪島市門前町走出        ,37.4962,137.2705,15.86,7.6,45292.67387,8.93,15.21
 LAT.=   37.2871,,,,,,,
 LON.=  136.7680,,,,,,,
 SAMPLING RATE= 100Hz,,,,,,,
 UNIT  = gal(cm/s/s),,,,,,,
INITIAL TIME = 2024 01 01 16 10 10,,,,,,,
 NS,EW,UD,,,,,

 

気象庁|強震観測データ|2024/1/1 石川県能登地方の地震

Pythonで全時間領域を対象にしてみたもの(画像はUD軸)

リンク先にある波形と比較するとほぼ類似の形状になってます

 

以下はRustで部分切り出し(全体で100サンプル/secで120,000フレーム、つまり120秒分のデータがありますが一番のピークの3,000~4012部分の切り出し)を、窓処理してFFTしてみたもの

<NS波形>

<NSスペクトラム>

以下はEW

以下はUD

 

NS/EWに比較すると周波数成分が高い方に出てきます、Pythonの全時間軸ともちろん傾向的には同じようなスペクトルになっています

X軸の20がほぼ10Hzに相当します

 

以下はPythonのコードになりますが、対話形式でほぼGeminiで作成させたコードがそのまま動きました、きちんと境界条件を与えてやれば人間がコードを書く手間を大幅に省力化できます、コードは読めないとダメですが

import numpy as np
import matplotlib.pyplot as plt

def fft_csv(filename, column_index, sampling_rate):
  """
  CSVファイルの特定列データをFFTする関数

  Args:
    filename: CSVファイルのパス
    column_index: FFTしたい列のインデックス (0から始まる)
    sampling_rate: サンプリングレート

  Returns:
    freqs: 周波数
    fft_result: FFTの結果
  """

  # CSVファイルを読み込む
  data = np.loadtxt(filename, delimiter=',', skiprows=1)  # ヘッダー行をスキップ

  # 指定した列のデータを取得
  target_data = data[:, column_index]

  # FFTを実行
  fft_result = np.fft.fft(target_data)

  # 周波数軸を作成
  N = len(target_data)
  freqs = np.fft.fftfreq(N, 1.0/sampling_rate)

  return freqs, fft_result

# 使用例

if __name__ == "__main__":
    filename = "noto.csv"  # CSVファイル名
    column_index = 2  # FFTしたい列 (3列目) 0 :NS/1 :EW/2 :UD
    sampling_rate = 100  # サンプリングレート

    freqs, fft_result = fft_csv(filename, column_index, sampling_rate)

# 結果をプロット (両対数プロット)
    plt.loglog(freqs, np.abs(fft_result))
    plt.xlabel("Frequency [Hz]")
    plt.ylabel("Amplitude")
    plt.title("FFT of Column {}".format(column_index+1))
    plt.grid(True)
    plt.show()

 

admin

 

micro:bitからのログの方法

Wi-Fi機能があれば簡単ですが、micro:bitには無いので普通はBLE使うのですが、BLEはいまいち使いづらい、

というわけで、もう一台micro:bitを用意してmicro:bit間は専用のradio機能で通信、受け側はUSB serialを使えば割と簡単にログが取れます。パソコンでのターミナルのシリアル動作はいまいち不安定(文字が抜ける)なのでMakeCodeのログ機能で表示させてみました、最終的にはProcessingで物体の状態を表示させるのが目的ですが、

micro:bitの送り側からはコンパス情報と加速度情報を送って、受け側にシリアル転送、MakeCodeのログ機能でビジュアル化しています。

<コンパス機能>

角度360から0は断絶してますが、micro:bitを徐々に回転させた時の数値の変化

<x軸の加速度>

micro:bitを手で左右(x軸方向)に振ってる状態

事前の処理は必要ですが、これらを使ってクラゲホバークラフトの安定化に使うつもり、

P.S. USB シリアルのデータ抜け、飛びはM1 Macで起こるけれどもIntel Macでは問題なさそうだ、MakeCodeではまともそうな理屈はつきませんが、

あと、MakeCode以外でUSBシリアル使う時にはパソコンのリブートでポート番号が変わるのは要注意

 

admin

 

 

 

 

 

 

 

シリカゲル再生

乾燥剤はものによっては再生可能らしいのでやってみた

要は熱を加えて水分追い出せば良いのだから、最初はフィラメント脱湿機でやってみたけど赤い色(吸湿状態)は数時間ではほぼ変化しない

で、世の中でよくやられているようにフライパン(弱火)で炒ってみる、これは顕著に変化して、徐々に赤玉が青玉に変化していく

写真は赤玉ほとんど見えなくなった状態なのでこの程度で完了、二、三回はこの方法で再生できそうだ、再生後は適度に空気を通す袋に入れて使用

 

admin

地震計を作ってみる(その4)— コードと回路からの考察

震度計算で気象庁から提示されているのは以下のリンクになります。

https://www.data.jma.go.jp/eqev/data/kyoshin/kaisetsu/calc_sindo.html

じゃ、近似計算でどの程度近似なのかをちょっと考察、

計算方法は① 加速度波形を周波数軸に変換(実質FFT)して、② 重み付けを行ない、さらに③ それを周波数に変換(実質IFFT)して、④ 0.3秒以上継続する値の最小値を求めて⑤ 震度計算式(対数目盛)で求めた値を四捨五入と切り捨てで震度とする、というステップになりますが、

近似計算と気象庁提示の差分のポイントは、②の周波数重み付けに差があります、このフィルターの特性は建物や構造物への影響度を考慮したものだと思われます

filter.png

近似計算方式では、ハイカット側はデジタル処理ではなくて、以下の回路図で加速度計に付加されているキャパシタ(0.1μF)で一次のカットオフ周波数30Hzぐらい(デフォルトでは内蔵の3300pFでカットオフ800Hzを変化させている、一方ロー側は格段の処理はされていない模様

コード(以下のリンク)でフィルター処理のコメントありますが、実質は平滑処理になってます

https://github.com/p2pquake/rpi-seismometer/blob/master/seismic_scale.py

とはいえ、FFTを使って計算するのとそれほどの差があるわけでもなさそうだから、実用的には十分じゃないかというところで、正確に震度を求めようとすると計測器を設置する工事だけでも大変なのだから

 

P.S. pythonでnumpyの機能にあるFFTを実行してみると、

M1 Macとラズパイzeroでの速度比較

<用意したデータ>
sampling_rate = 2000  # サンプリング周波数(Hz)
T = 1 / sampling_rate  # サンプリング間隔
t = np.arange(0, 1.0, T)  # 時間ベクトル

# 信号生成(50Hzと120Hzのサイン波を重ねたもの)
f1 = 100  # Hz
f2 = 300  # Hz
signal = np.sin(2*np.pi*f1*t) + 0.5*np.sin(2*np.pi*f2*t)

<実行速度>
M1 Mac:		np.fft.fft:     0.000027 [sec] 
ラズパイゼロ:	np.fft.fft:	 0.001830 [sec] 

ふーむ、およそ60倍ぐらい違うか、想定範囲だけど

ラズパイzeroでもフレーム周期5msでできなくはなさそうなレベル

 

admin

FromとInto変換できる浮動小数と整数の精度条件(@Rust)

まあどちらもトレイトで定義されているわけで、対応する型が定義されてなければ変換できないわけですが、Begginig Rustのコードで浮動小数点に整数から変換するコードが出てきますが、テキストではi32をfloat変換するには相手先はf64でなければできないとあります。

https://doc.rust-lang.org/std/convert/trait.From.html

で該当部分を抜き出すと、

impl From<i16> for f32
impl From<i16> for f64
~
impl From<i32> for f64

i32からfloatに変換するときにはf32ではダメで、f64になるよということで無理に変換しようとするとエラーメッセージは、

the trait `From<i32>` is not implemented for `f32`

なので、そういうことです。i32の精度はf32では保持できないから変換に意味がないから用意されてないということです。

 

admin