胡瓜のプログラミング日記

Azure OpenAI と Open AI (ChatGPT) の重要な違い

いろんなところでいろんな人が言及しているけど、かなり重要な違いがあるのでメモ。

Azure OpenAI はユーザーの学習データを自分たちのモデルの学習に使わない

https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance

The training data (prompt-completion pairs) submitted to the Fine-tunes API through the Azure OpenAI Studio is pre-processed using automated tools for quality checking including data format check. The training data is then imported to the model training component on the Azure OpenAI platform. During the training process, the training data are decomposed into batches and used to modify the weights of the OpenAI models. Training data provided by the customer is only used to fine-tune the customer’s model and is not used by Microsoft to train or improve any Microsoft models.

Azure OpenAI Studio から Fine-tunes API に送信された学習データ(プロンプトとコンプリーションのペア)は、データ形式チェックなどの品質チェックのための自動ツールを使って前処理が行われます。その後、学習データは、Azure OpenAI プラットフォーム上のモデル学習コンポーネントにインポートされます。学習プロセスでは、学習データはバッチに分解され、OpenAI モデルの重みを修正するために使用されます。 お客様から提供された学習データは、お客様のモデルの微調整にのみ使用され、MicrosoftMicrosoft のモデルを学習または改善するために使用されることはありません。

"training data" であって、じゃあ実際のモデルとのやりとりはどうなの?と思ったけどそこまでは調べきれず。
さすがに「学習データは使わないけど、実際のやりとりは使います」というだまし討ちみたいなことはやらないだろうと思う。
あと、今は利用できるユーザーをかなり制限していて、専用のフォームからリクエストして審査を受ける必要がある。
フォームの注意事項には「個人からのリクエストは受け付けない」みたいなことが書いてあるので、個人で試すことはできないっぽい。

OpenAI(ChatGPT) はユーザーのデータを自分たちのモデルの学習に使う

OpenAI について https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance

As part of this continuous improvement, when you use OpenAI models via our API, we may use the data you provide us to improve our models. Not only does this help our models become more accurate and better at solving your specific problem, it also helps improve their general capabilities and safety.

この継続的な改善の一環として、お客様が OpenAI のモデルを API 経由で使用する場合、当社は、お客様から提供されたデータを使用して、当社のモデルを改善することがあります。これは、私たちのモデルが、より正確で、あなたの特定の問題を解決するのに役立つだけでなく、一般的な能力と安全性を向上させるのにも役に立ちます。

ChatGPT について https://help.openai.com/en/articles/6783457-chatgpt-general-faq

  1. Will you use my conversations for training?
    Yes. Your conversations may be reviewed by our AI trainers to improve our systems.

とのこと。
OpenAI の方の "the data you provide us" というのが Fine tuning のための学習データだけを差すのか、実際の API とのやりとりも含むのかはこのページだけでは読み取れず。そもそもユーザーは"us"に対して提供したつもりはないのではないかと思うのだけれども。
ただ、ChatGPT の方では会話を学習に使うと明言しているし、API の方も同様だと考えた方がよいだろう。

所感

現時点で OpenAI を業務で使うのは厳しいのでは?という印象。
会社の業務固有の知識を大量に与えれば簡単に社内ヘルプ的なの作れないかなとか考えていたのだけれど。
お試しでいろいろ触っておいて、Azure OpenAI が広く利用できるようになるのを待とう。あるいは Google のやつか。

JavaScriptにおけるvar/let/constの違い

自分がこの業界で働きはじめたころにはすでに var はほとんど過去のものであったため、
その仕様についてちゃんと調べる機会がなかった。
しかし、先日初心者に質問される機会があり、そこでようやく var が let や const とどう違うかしったのでメモ。

やっぱり mdn web docs を見るのが一番。https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Grammar_and_types#%E5%A4%89%E6%95%B0%E3%81%AE%E5%AE%A3%E8%A8%80

スコープが違う

var について

この構文は、実行コンテキストによって、ローカル変数とグローバル変数の両方の宣言に使用できます。

let, const について

例えば、let y = 13。この構文はブロックスコープのローカル変数を宣言することができます。(以下にある変数のスコープをご覧ください。)

とある。
「以下にある『変数のスコープ』」 https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Grammar_and_types#%E5%A4%89%E6%95%B0%E3%81%AE%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97
によれば、

let および const の宣言は、宣言されたブロック文のスコープになることもあります。
ただし、 var で生成された変数はブロックスコープにはならず、そのブロックが存在する 関数(またはグローバルスコープ) に局所的になります。

つまり、let や const はブロックスコープになるが、var はブロック外でも使用可能。

変数の巻き上げ

var で宣言された変数は巻き上げが行われ、その変数がまだ宣言されていない場合でも、そのスコープ内のどこでも参照することができるようになります。

つまり、以下のように書いても、エラーにはならない。
x の初期化処理は巻き上げが行われないため、コンソールには undefined が出力される。

console.log(x);
var x = 3;
// => undefined (エラーではない)

一方で、const を使って書いた場合は「Uncaught ReferenceError: x is not defined」となる。

console.log(x);
const x = 3;
// => Uncaught ReferenceError: x is not defined

所感

var だけで実装してた先達の皆さんへ敬意を。。。

参考

Visual Studio Code Markdown Preview EnhancedのPlantUMLをアップデートする

諸々必要なもの

手順

Markdown Preview Enhanced に含まれる jar を直接置き換える
基本的にはこのページの手順通り。 https://otepipi.hatenablog.com/entry/20210520/1621458229

ただし、Windows の場合、Windows 側と WSL 側で.vscode/extensions フォルダは別々に存在する。
場所はどちらもユーザーのホームディレクトリにある.vscode から上記のブログの通りにたどれば OK。

参考

ひたすら記事を書くハードルをさげていく...

Google Sheets API メモ

諸々必要なもの

次にやりたいこと

  • スタイルを変えたい
  • Vue と React を共存させられるらしいのでちょっと調べる

参考

Jenkinsの学習

参考書籍など(随時更新)

継続的インテグレーションに必要なもの

Jenkinsを使ってみる

ビルド結果メール通知の設定(Gmailを使用)

  • 設定方法
    1. Googleアカウントで2段階認証を設定->アプリパスワードを生成
    2. 生成したパスワードをJenkins側で入力stackoverflow.com
  • その他
    • 日本語のQiitaやブログだとGoogleアカウントのセキュリティを下げる方法で書いているのが多かった

simple-java-maven-app tutorial の実施

github.com

    pipeline {
        agent {
            docker {
                image 'maven:3-alpine' 
                args '-v /root/.m2:/root/.m2' 
            }
        }
        stages {
            stage('Build') { 
                steps {
                    sh 'mvn -B -DskipTests clean package' 
                }
            }
        }
    }    
  • あともチュートリアル通りに実施
  • 間違えたらすぐにコンテナ破棄してやり直せるのがよい

JenkinsとSubversionの連携

    version: "2.0"
    services:
    subversion:
        image:  kuchida1981/subversion-httpd
        environment:
        - SVN_DEFAULT_USER=username
        - SVN_DEFAULT_USER_PASSWD=password
        - SVN_REPOSITORY_DESCR="My Repositories"
        - SVN_DEFAULT_REPOSITORY=repositoryname
        ports:
        - "88:80"
        - "444:443"
        - "2222:22"
        volumes:
        - './subversion_home:/var/svn'
        container_name: subversion
    jenkins:
        image: jenkins/jenkins:lts
        ports:
        - 8090:8080
        volumes:
        - './jenkins_home:/var/jenkins_home'
        container_name: jenkins
  • 次はジョブの作成

Javaメモ 参照の値渡し

参照やら参照渡しやらは、いつも

「『あぁ、あれね』⇒ そういえばどうだっけ… ⇒ 『あぁ、そっか』…」

の繰り返し。twitterで流れてきたものを確認し、忘れないうちにメモ。

public static void main(String[] args) {
	// ArrayListインスタンスの生成(右辺)で確保された領域の先頭番地をlistに代入
	ArrayList<String> list = new ArrayList<String>();
	// list の値が指す領域に"Hello"を追加
	list.add("Hello");
	// listの値(listそのものではない)をmethodに渡す
	method(list);
	System.out.println(list);
}

private static void method(ArrayList<String> list){
	// listの値が指す領域に"こんにちは"を追加
	list.add("こんにちは");     // ⇒ [Hello, こんにちは]
}

・「list.add("こんにちは")」のlistは、main 側のlistと同じ値をもつだけで、main側のlistそのものではない。
・が、methodではlistの値がさす領域にあるArrayListそのものに対して操作(add)をしているので、「こんにちは」が追加される。

public static void main(String[] args) {
	ArrayList<String> list = new ArrayList<String>();
	list.add("Hello");
	method(list);
	System.out.println(list);
}

private static void method(ArrayList<String> list){
	// listに新たなArrayListインスタンスを代入。main側のlistには影響なし。
	list = new ArrayList<String>();   
	list.add("こんにちは");    // ⇒ Hello
}

・method側のlistには、mainで生成したものとは別のインスタンスの生成で確保された領域を指す値が入る
・method側のlistは、前述の通りmain側のものとは値が同じだけの別物なので、「System.out.println(list)」のlistの値が指す領域のインスタンスには影響しない

C言語で中途半端にポインタやっちゃった影響がある気がする…ちゃんと理解できていれば大丈夫なんだろうけど。

ABC007-C 幅優先探索(AtCoder精進記録)

C - 幅優先探索

AtCoder Beginner Contest 007-C

〇問題
・'x# : 壁、'.' : 道
例:

########
#......#
#.######
#..#...#
#..##..#
##.....#
########

スタートとゴールが与えられ、その最短経路の歩数を求める。

〇方針
幅優先探索

ソースコードC言語

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>

int row,column;
char c[51][51]; 
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
bool reached[50][50];
int qx[3000],qy[3000];
int step[51][51];
int head=0,tail=1;

// 幅優先探索
void bfs(int x,int y);

int main()
{
    int row_start,column_start;
    int row_goal,column_goal;
    scanf("%d%d",&row,&column);
    scanf("%d%d",&row_start,&column_start);
    scanf("%d%d",&row_goal,&column_goal);
    for(int i=0;i<row;i++){
        scanf("%s",c[i]);
    }

    bfs(row_start-1,column_start-1);
    printf("%d\n",step[row_goal-1][column_goal-1]);

    return 0;
}

void bfs(int x,int y){
    reached[x][y] = true;
    qx[0] = x;
    qy[0] = y;
    step[x][y] = 0;
    while( head != tail ){
        // Pop(取り出し)
        int poped_x = qx[head];
        int poped_y = qy[head];
        head++;
        for(int i=0;i<4;i++){
            int nx = poped_x + dx[i];
            int ny = poped_y + dy[i];
            // 迷路の範囲内であるか
            if( ( nx >= 0 ) && ( nx < row ) && ( ny >= 0 ) && ( ny < column ) ){
                // まだ未到達かつ道であるか
                if( (reached[nx][ny] == false) && ( c[nx][ny] == '.' ) ){
                    step[nx][ny] = step[poped_x][poped_y] + 1;
                    reached[nx][ny] = true;
                    // Push(追加)
                    qx[tail] = nx;
                    qy[tail] = ny;
                    tail++;
                }
            }
        }
    }
}

〇所感
・聞いたことはあるけど実装したことがないやつ。あいまいな理解だったところがようやくすっきりした。
・もうちょい練習は必要かな…
深さ優先探索もそうだけど、これを知らずによくC問題まで安定して解いてんな…と思った。今までは運がよかっただけかも。

〇参考記事
AtCoder 版!蟻本 (初級編) (問題の選択)

〇参考コード
Submission #1960299 - AtCoder Beginner Contest 007
 チラ見して、考えて、チラ見して…って感じに使わせていただいた。