[Swift] 25 Apple WatchのComplication改良 カレンダー / 時計の針で読めない際の対策

[M1 Mac, Ventura 13.3.1, Xcode 14.3]

Complicationの改良カレンダーですが、アナログ時計のため時針や分針が重なると読みにくくなります。

カレンダーが読みにくい

そこでタップすると日時を表示するようにしました。デジタル時計は止まったまま動きません。

タップすると表示
import SwiftUI

struct ContentView: View {
    let date: Date
    
    var body: some View {
        VStack (spacing: 20){
            Text(getFormattedDate())
            .font(.system(size: 30))
            .foregroundColor(.green)
            
            Text(getFormattedWeekday() + "曜日")
            .font(.system(size: 30))
            .foregroundColor(.yellow)
            
            Text(getFormattedTime())
            .font(.system(size: 30))
            .foregroundColor(.blue)

        }
        .padding()
    }
    
    func getFormattedDate() -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy/MM/dd"
        return dateFormatter.string(from: date)
    }
    
    func getFormattedWeekday() -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "E"
        dateFormatter.locale = Locale(identifier: "ja_JP")
        return dateFormatter.string(from: date)
    }
    
    func getFormattedTime() -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "HH:mm:ss"
        return dateFormatter.string(from: date)
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(date: Date())
    }
}

[Swift] 24 Apple WatchのComplication改良 カレンダー / 月表示追加

[M1 Mac, Ventura 13.3.1, Xcode 14.3]

改良カレンダーのフォントサイズを調整して3行にし、月表示を追加しました。

ChatGPTが考えたコードを微修正しています。

struct DateToolComplicationEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        VStack (spacing: -5){
            Text(getWeekday(entry.date))
            .font(.system(size: 18))
            .foregroundColor(.yellow)
             
            Text(getMonth(entry.date))
            .font(.system(size: 18))
            .foregroundColor(.green)

            Text(getDay(entry.date))
            .font(.system(size: 20))
            .foregroundColor(.white)
        }
    }
    
    func getWeekday(_ date: Date) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "E"
        dateFormatter.locale = Locale(identifier: "ja_JP")
        return dateFormatter.string(from: date)
    }
    
    func getMonth(_ date: Date) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "M"
        return dateFormatter.string(from: date)
    }

    func getDay(_ date: Date) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "d"
        return dateFormatter.string(from: date)
    }

}

[Swift] 23 Apple WatchのComplication改良 カレンダーの視認性向上

[M1 Mac, Ventura 13.3.1, Xcode 14.3]

Complicationのカレンダーがとても見にくいカラー構成になっているため、フォントサイズと合わせて改良しました。以下の手順になります。

1.watchOS Appのプロジェクトを作成する。
2.Hello World表示のままコードに手を加えずにWidget Extensionを追加する。
3.swiftコードのEntryViewを以下のように書き換える。今回コードはChatGPTに考えさせた。

struct DateToolComplicationEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        VStack {
            Text(getWeekday(entry.date))
            .font(.largeTitle)
            .foregroundColor(.yellow)
            
            Text(getDay(entry.date))
            .font(.largeTitle)
            .foregroundColor(.white)
        }
    }
    
    func getWeekday(_ date: Date) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "E"
        dateFormatter.locale = Locale(identifier: "ja_JP")
        return dateFormatter.string(from: date)
    }

    func getDay(_ date: Date) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "d"
        return dateFormatter.string(from: date)
    }
}

4.ビルド後、Apple Watch実機にてComplicationに改良カレンダーを登録し文字盤に表示させる。

既存カレンダー
改良カレンダー

Apple Watchは21年1月から使用していますが、当初からカレンダーの視認性が低いと思っていました。2年と6ヶ月が経ち、ようやくChatGPTの力を借りて解決できました。

ただ画面ロック時にメモアプリと共に表示がブランクになってしまいます。ChatGPTのGPT-4でも解決策は分からず、Stack Overflow英語版やApple開発者フォーラムにも情報はありませんでした。

ロック時の文字盤

プログラミングはAIを使いこなすことでかなりハードルが下がりますね。記憶力よりも応用力の時代になっていくのでしょうか。

[Swift] 22 メモアプリ製作 その8 Complications対応

[M1 Mac, Ventura 13.3.1, Xcode 14.3]

メモアプリを以下の方法でComplicationsに対応させ、Apple Watch文字盤にアイコンを表示させてタップで呼び出せるようにしました。

1.Xcodeの[File]-[New]-[Target]でwatchOSタブにあるWidget Extensionを選択し進めていくと、新ターゲットとしてプロジェクト内にディレクトリが作成される。”Include Configuration Intent”のチェックは外しておく。

2.swiftコードのEntryViewの内容を適当に書き換える。デフォルトではデジタル時計になっている。今回はChatGPTに考えてもらったコードをペーストした。アイコンとしてシステム画像”square.and.pencil”を表示する。

struct MemoToolAW_ComplicationsEntryView : View {
    var entry: Provider.Entry // 他のコードで使うので消さずに残しておく

    var body: some View {
        Image(systemName: "square.and.pencil")
        .resizable()
        .aspectRatio(contentMode: .fit)
        .foregroundColor(.white)
        .background(Color.blue)

//        Text(entry.date, style: .time) // デフォルトはデジタル時計
    }
}

3.ビルド後、Apple Watch実機にてComplicationにメモアプリを登録し文字盤に表示させる。

メモアプリは左の青いアイコン

これまで使っていたメモアプリNotebookはComplicationから起動させると最初に音声入力画面になり内容を表示させるにはこれをキャンセルする必要がありました。今回作ったメモアプリはいきなり内容表示になるので手間が減りました。

参考サイト

[Swift] 15 メモアプリ製作 その1

[M1 Mac, Ventura 13.3.1, Xcode 14.3]

iOS, watchOS, iPadOS, macOSで使えるメモアプリの製作に取り掛かりました。

とりあえず叩き台のコードをChatGPTに作成してもらいました。

あっさり作ってくれてちょっと引いています。

非IDEにこだわらなければ、Xcodeにどっぷり依存で簡単なアプリを量産できそうです。

import SwiftUI

struct Memo: Identifiable {
    let id = UUID()
    let title: String
    let content: String
}

struct MemoListView: View {
    @State var memos: [Memo] = [
        Memo(title: "メモ1", content: "これはメモ1です。"),
        Memo(title: "メモ2", content: "これはメモ2です。"),
        Memo(title: "メモ3", content: "これはメモ3です。")
    ]
    
    var body: some View {
        NavigationView {
            List(memos) { memo in
                NavigationLink(destination: MemoDetailView(memo: memo)) {
                    Text(memo.title)
                }
            }
            .navigationBarTitle("メモ一覧")
            .navigationBarItems(trailing: NavigationLink(destination: MemoEditView(memos: $memos)) {
                Image(systemName: "plus")
            })
        }
    }
}

struct MemoDetailView: View {
    let memo: Memo
    
    var body: some View {
        VStack {
            Text(memo.title)
                .font(.title)
            Text(memo.content)
                .padding()
            Spacer()
        }
        .navigationBarTitle(memo.title)
    }
}

struct MemoEditView: View {
    @Binding var memos: [Memo]
    @State var title: String = ""
    @State var content: String = ""
    
    var body: some View {
        Form {
            Section(header: Text("タイトル")) {
                TextField("タイトルを入力してください", text: $title)
            }
            Section(header: Text("内容")) {
                TextEditor(text: $content)
            }
            Section {
                Button(action: {
                    let memo = Memo(title: title, content: content)
                    memos.append(memo)
                }) {
                    Text("保存")
                }
            }
        }
        .navigationBarTitle("新規メモ")
    }
}

[AI] GPT 0613版リリース, 関数呼び出し機能 Function API追加

GPT-4とGPT3.5の0613版がリリースされました。この最新版で関数呼び出し機能 Function APIが追加されました。

天気APIを使ったコード例がネット記事に掲載されていたので、早速内容をチェックしました。

参考記事

GPT 0613版 Function APIのフロー

ChatGPTに指示文とfunctionsパラメータ、function_callパラメータを送信する。

ChatGPTが必要と判断したらfunction名と引数を返信する。

利用者側はこれを受け、function名と引数をパラメータとして取込み再度送信する。

functionの戻り値を組み込んだレスポンスを返す。

天気APIを利用する場合

“東京の現在の天気を教えてください。”と送信する。(functionsパラメータ他もバックグラウンドで同時に送信)

<コードの一部>
response = openai.ChatCompletion.create(
model="gpt-4-0613",
messages=[{"role": "user", "content": text}],
functions=[weather_function],
function_call="auto",
)


ChatGPTはweather_functionの使用が必要と判断し、引数(緯度、経度)とともに返信。

利用者側はweather_functionの使用を指示するプロンプトを自動送信。

ChatGPTは天気APIから得られた情報を元に返信。
“東京の現在の天気は20.9℃で、風速は4.2 m/s、風向きは北北西329.0度です。天候コードは2で、おおむね晴れています。ただし、現在は夜間です。”

OpenAI社にあまり課金していないのでGPT-4 APIやChatGPT plugins APIを使わせてもらえない身ではありますが、これでプラグインと同等の機能を自製できるようになりました。

開発中のChatGPTアプリにも取り入れたいと思います。

[AI] ChatRWKVアプリ製作 その12 Mac版メモリ制限解除

[M1 Mac, Ventura 13.3.1, Python 3.10.4, PyTorch 2.0.0]

Mac版を改良しメモリの制限を解除できるようにしました。

def loadModel(self):
    self.box.setStyleSheet('background-color: #3E62AD')
    self.output.setText("")
    
    # PyTorch環境変数設定
    limitoffChecked = self.limit.isChecked()
    
    if limitoffChecked == True:
        os.environ['PYTORCH_MPS_HIGH_WATERMARK_RATIO'] = '0.0'
    else:
        try:
            del os.environ['PYTORCH_MPS_HIGH_WATERMARK_RATIO']
        except:
            pass

    try:
        print(f'PYTORCH_MPS_HIGH_WATERMARK_RATIO = {os.environ["PYTORCH_MPS_HIGH_WATERMARK_RATIO"]}\n')
    except:
        print('PYTORCH_MPS_HIGH_WATERMARK_RATIOは設定なし\n')

<以下略>

[AI] ChatRWKVアプリ製作 その11 M1 Mac / Metalで再挑戦

[M1 Mac, Ventura 13.3.1, Python 3.10.4, PyTorch 2.0.0]

ChatRWKVの設定により7Bサイズのモデルを読み込めるようになりました。

環境変数 PYTORCH_MPS_HIGH_WATERMARK_RATIOをゼロに設定しメモリ使用の上限を撤廃することで読込が可能になります。ただしシステムが不安定になる可能性があるため要注意です。

動作はかなり遅く実用にはほど遠いですが、RAMメモリ強化でどこまで速くなるのか興味深いです。

ところでAppleのイベントWWDCが今晩開催されますが(日本時間6/6 午前2時)、AIについてどのような発信があるのか楽しみです。

またグランフロント大阪にApple Storeを出店する計画があるとか。実現したらヨドバシ梅田と同様に売り上げ日本一になるのでは。

import os

# PyTorch環境変数設定
os.environ['PYTORCH_MPS_HIGH_WATERMARK_RATIO'] = '0.0'
print(f'PYTORCH_MPS_HIGH_WATERMARK_RATIO = {os.environ["PYTORCH_MPS_HIGH_WATERMARK_RATIO"]}\n')
self.stratChoice = QComboBox(self)
self.stratChoice.setGeometry(215,70,100,25)
self.stratChoice.addItem('mps fp32 -> cpu fp32 *10')
self.stratChoice.addItem('mps fp32')
self.stratChoice.addItem('cpu fp32')
self.stratChoice.addItem('cuda fp16')
7Bでは環境変数を変更しないとエラーになる
環境変数変更で7Bは読み込めたが動作はかなり遅い

[AI] ChatRWKVアプリ製作 その10 Raven 7Bと14Bの比較

[RTX 4070Ti, Ubuntu 22.04.1, CUDA 11.8, PyTorch 2.0.0]

最新バージョン12、7Bモデル(14.8GB)と14Bモデル(28.3GB)の性能を比較しました。

日本語については全く学習内容に含まれておらず、質問してもAIから有用な回答は返ってきませんでした。1%でも含まれていると大分違います。

英語でプログラミングについて質問するとやはり14Bの方が明らかに優れています。コンテキストを読み取る能力に格段の差があります。7Bについてはいくらバージョンアップしても根本の能力は変わらないように感じました。絶対能力の向上を期待していたのですが厳しいようです。

Japanese - /home/xxx/AI/Model/RWKV-4-Raven-14B-v12-Eng98%-Other2%-20230523-ctx8192.pth - cuda fp16i8 -> cpu fp32 *10

あなたはプログラミングを教えるチャットボットです。

Human: QCoreApplication::exec: The event loop is already running
Code now datetime by yymmdd_hhmmss in Python
AI: You can use the datetime module in Python to format a datetime object with the format yymmdd_hhmmss. Here's an example:
```python
import datetime
now = datetime.datetime.now()
formatted_datetime = now.strftime('%Y%m%d_%H%M%S')
print(formatted_datetime)
```This will output a string in the format yymmdd_hhmmss, such as 20190705_130056. You can use this string in any program that requires a datetime object.

Human: QCoreApplication::exec: The event loop is already running
Japanese - /home/xxx/AI/Model/RWKV-4-Raven-7B-v12-Eng49%-Chn49%-Jpn1%-Other1%-20230530-ctx8192.pth - cuda fp16i8 -> cpu fp32 *10

あなたはプログラミングを教えるチャットボットです。

Human: QCoreApplication::exec: The event loop is already running
Code now datetime by yymmdd_hhmmss in Python
AI: import datetime from datetime import datetime, timezone def yymmdd_hhmmss(dt): y, m, d = map(int, dt.split('_')) return timezone(y).localize(dt.replace(hour=0, minute=0, second=0), tzinfo=timezone(datetime.timezone(m)).normalize())

Human: QCoreApplication::exec: The event loop is already running

RWKV学習モデル

[AI] RWKV LoRA追加学習検証

[RTX 4070Ti, Ubuntu 22.04.1, CUDA 11.8, PyTorch 2.0.0]

AI研究用PCでRWKV-14Bモデル(28.3GB)の追加学習を試みましたが、RAMが足りませんでした。仮にマザボ(B660チップセット)の最大である128GBに増設しても、今度はVRAMが足りなくなるものと思われます。

strategy設定をdeepspeed_stage2_offloadやdeepspeed_stage3_offloadにしても上手くいきませんでした。

プログラミング学習用途では7Bは能力不足なので、LoRAによる自力でのチューニングは一旦あきらめます。

deepspeed_stage3_offloadではRAM 64GBを消費して強制終了した(中段赤ライン)