James Tsang

James Tsang

A developer.
github
twitter
tg_channel

ARTS チェックイン 8 日目 - Prompt Engineering、DemoGPT、および Get Hands Dirty

A:27. Remove Element#

与えられた配列 nums と値 val があります。val と等しい要素をすべて「インプレース」で削除し、削除後の配列の新しい長さを返します。
追加の配列スペースは使用しないでください。O (1) の追加スペースのみを使用して、入力配列を「インプレース」で変更する必要があります。
要素の順序は変更できます。新しい長さの後に配列の残りの要素を考慮する必要はありません。
注:
なぜ数値を返すのに、答えが配列なのかと思うかもしれませんが、入力配列は「参照」として渡されるため、関数内で入力配列を変更すると、呼び出し元にも反映されます。
以下のような内部操作を想像することができます:
//nums は「参照」として渡されます。つまり、引数に対してコピーは作成されません
int len = removeElement(nums, val);
// 関数内で入力配列を変更すると、呼び出し元にも反映されます。
// 関数の返り値の長さに基づいて、配列内の要素の範囲を印刷します。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

例 1:
入力:nums = [3,2,2,3], val = 3
出力:2, nums = [2,2]
説明:関数は新しい長さ 2 を返す必要があり、nums の最初の 2 つの要素は 2 です。新しい長さの後に配列の残りの要素を考慮する必要はありません。例えば、関数が新しい長さ 2 を返し、nums = [2,2,3,3] または nums = [2,2,0,0] の場合でも、正しい答えと見なされます。

例 2:
入力:nums = [0,1,2,2,3,0,4,2], val = 2
出力:5, nums = [0,1,4,0,3]
説明:関数は新しい長さ 5 を返す必要があり、nums の最初の 5 つの要素は 0, 1, 4, 0, 3 です。新しい長さの後に配列の残りの要素を考慮する必要はありません。

function removeElement(nums: number[], val: number): number {
  for (let i = 0; i < nums.length; i += 1) {
    if (nums[i] === val) {
      nums.splice(i, 1)
      i -= 1
    }
  }
  return nums.length
}

提出結果:

113/113 cases passed (76 ms)
Your runtime beats 18.87 % of typescript submissions
Your memory usage beats 98.31 % of typescript submissions (42.1 MB)

問題は比較的簡単で、LeetCode をやったことがないので、Easy の問題から始めて、手を動かしてみることにしました。ただし、長期的には、このような低レベルの問題を繰り返し解くことは、向上には役立たないと思います。後で述べるように、意図を解決するための心理的な表現を形成するために、難易度を上げる計画を立てる必要があります。問題を解くことによって、問題を解決するための心理的な表現を形成することなく、問題を解決することは容易に忘れられる可能性があるためです。

R:Prompt Engineering#

ほとんどの Prompt Engineering チュートリアルは、8 ページの価値がないほど短いです。各テクニックは、いくつかの例で説明するだけで十分です。残りの内容は、ベンチマークテストです。より使いやすいベンチマークテストの基盤は、コミュニティにとっても有用ですが、反復的な Prompt と外部ツールの使用は容易ではありませんし、コミュニティに採用されることも困難です。

基本的な Prompt#

ゼロショット#

タスクのテキストをモデルに直接入力して結果を得る。

フューショット#

フューショットは、タスクのテキストの前に、いくつかの高品質なクエリと返される例を事前に与えることで、モデルに意図をよりよく理解させるものですが、これはより多くのトークン数を使用することを意味します。

いくつかの研究では、これらのフューショットの例の形式、内容、順序がモデルの出力に大きな影響を与えることがわかっています。

さらに、分類タスクでは、サンプルのラベル分布のバイアス、ラベルの位置のバイアス、一般的なトークンのバイアスなども考慮する必要があり、入力が N/A(個人的な理解では空の入力)の場合には、出力ラベルの確率を調整してこのバイアスを相殺する必要があります。

著者はいくつかの例の提供方法について触れています:多様性のある選択、比較的な例、例の位置をランダムに決定するなど。

インストラクションプロンプティング#

フューショットは、モデルに意図をよりよく理解させるためのものですが、入力の長さに制限があります。意図をモデルによりよく理解させるためには、モデルに直接指示を与えることもできます。

InstructGPT は、ユーザーの意図をよりよく理解するためにトレーニングされた言語モデルです。RLHF は、この目的を達成するための一般的な方法です。この方法を使用すると、モデルによりよくユーザーの意図を理解させることができ、モデルとの対話のコストも削減することができます。

インストラクションモデルでは、要件を詳細に説明する必要があります。モデルにやってほしくないことがある場合は、それを指摘するだけでなく、やってほしいことを指示する必要があります。

インコンテキストインストラクションラーニングは、フューショットとインストラクションプロンプティングを組み合わせて、「タスクの定義」、「入力」、「出力」を含むいくつかの例を提供します。

自己整合サンプリング#

自己整合サンプリングは、複数の temperature > 0 の出力を生成し、その中で最も良い効果を選択することを指します。(個人的には、これが Prompt の構築とどのように関連しているのかはわかりませんが、Prompt の構造や機能に影響を与えないようにするために、複数回実行して最も効果のあるものを選択するという意味だと思います)

Chain-of-Thought (CoT)#

CoT は、タスクの推論ロジックをステップバイステップで説明するために、一連の短い文を使用して最終的な答えを得るものです。このテクニックは、複雑なタスクにのみ明らかな効果があり、簡単なタスクではほとんど効果がありません。CoT は、ゼロショットやフューショットと組み合わせて使用することもできます。

自動プロンプト設計#

Prompt は、一連の前置トークンシーケンスと見なすことができるものであり、このシーケンスによってユーザーの入力時に望ましい出力を得ることができます。したがって、この前置トークンシーケンスをトレーニング可能なパラメータとして扱い、勾配降下法を使用してベクトル空間で最適化することができます。AutoPrompt、Prefix-Tuning、P-tuning、Prompt-Tuning などは、このアイデアを基にしており、これらの方法の進化の方向性は、構築プロセスをますます簡単にすることです。

自動プロンプト設計は、モデルが生成する指示を選択するための方法であり、指示プール内でスコア関数を使用して最も効果のある指示を選択します。

さらに、CoT の指示を自動的に構築する方法もあります:augment-prune-select:

  1. Augment:ゼロショットまたはフューショットを使用して、与えられた問題の複数の仮の思考チェーンを生成します。
  2. Prune:生成された答えが事実と一致するかどうかに基づいて、仮の思考チェーンを剪定します。
  3. Select:採用する思考チェーンを選択するためにいくつかの数学的な手法を適用します。(著者は言及していますが、私自身は理解していません)

拡張言語モデル#

適切なテクニックと外部ツールを使用することで、言語モデルの効果を向上させることができます。

検索#

大規模なモデルを使用する場合、最新の情報やプライベートな情報と組み合わせる必要がある場合があります。この場合、検索サービスを使用して関連する情報を Prompt に追加できます。

プログラミング言語の推論#

PAL (Program-aided language models) と PoT (Program of Thoughts prompting) は、LLM が自然言語推論の問題を解決するためにプログラミング言語の結果を生成し、それを Python インタプリタなどで実行することを目指しています。これには、モデル自体がプログラミングに関する強力な能力を持っていることが必要です。

外部 API#

TALM (Tool Augmented Language Models) は、テキストからテキストの API 呼び出しを使用して強化された言語モデルです。(個人的には、これは OpenAI の Function Calling に似ているように思えます)

T:DemoGPT - Prompt を入力して Web アプリケーションを取得#

DemoGPT は、Prompt からアプリケーションへの新しい形式の探索です。これまで見てきた Prompt からアプリケーションへの製品は、基本的には Prompt に基づいたアプリケーションデザインのルールに従って構築する必要があります。例えば、OpenGPTLangflow のようなものです。DemoGPT は、Prompt から直接アプリケーションに到達する新しいアプローチと見なすことができます。アプリケーションの実装フレームワークは、Gradio よりも強力な Streamlit に Langchain を追加したものです。(私は Streamlit にますます期待しています)

S:Get Hands Dirty#

LLM 向けのアプリケーションをいくつか作ってきましたが、基本的には Prompt の簡単なカスタマイズを行い、ツール化または API 化してきました。競争力のある、持続可能な AI アプリケーションを作るためには、問題の理解には記事を読むことが必要ですが、それをうまくやるには実際に手を動かす必要があります。おそらく、情報フローと知識管理システムの Web アプリケーションを作成して、この目標を達成することができるかもしれません。


参考文献:

  1. ARTS 打卡活动
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。