Gemini Proでリファクタ・テキスト要約・画像説明など色々試してみる

Google開発のLLMモデルであるGeminiが今年12月にリリースとなりました。
国内外でも注目されており、機能として同じような立ち位置にあるChatGPTとGeminiでどちらが良いのか気になっている人が多いでしょう。今回、Gemini Proを触ってみて所感をちょっとでもお伝えできればと思います。

## Geminiのベンチマーク
Googleが出しているGeminiの性能を測るベンチマークでは驚くべき結果になっています。露骨にChatGPT（GPT-4）と比較していますが、ほとんどの指標でGeminiが上回るという結果になっています。（ポジショントークもあるでしょうが・・・）

![スクリーンショット 2023-12-21 12.43.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707936/71f3028e-9e07-2216-1952-4a870d2e5ac7.png)

引用：[Gemini: A Family of Highly Capable Multimodal Models](https://storage.googleapis.com/deepmind-media/gemini/gemini_1_report.pdf)
ただし、Geminiのグレードも色々あり、Gemini Ultra>GPT-4>Gemini Proみたいな結果になっています。


## Geminiの使い方（準備）
 Geminiを使用するには、ライブラリのインストール・APIキーの作成をすれば誰でも使用することができます。
私はpipで入れましたが、パッケージ管理ツールで対応しているかというと微妙なのでしばらくはpipで入れて使用したいと思います。

 ```
 # pipでのインストール方法
 pip install -q -U google-generativeai
 ```

 APIキーの発行は、Googleアカウントで作成するかGoogle Cloudを経由するかがあります。
 手軽に試したいなら、簡単なGoogleアカウント発行がおすすめです。
 下記リンクに従って登録を進めるだけで、APIキーが発行されます。
 
 https://ai.google.dev/

APIキーはそれぞれで保管してください。

## GeminiProを試してみた！
本題であるGeminiを実際に試してみたいと思います。使用する環境はGoogle Colabolatoryです（簡単かつ安定動作しているそうなので）。現状できることを色々試して出力結果がどうなるのかみていきます。
まずは一般的にLLMでの用途を試してみます。

使う前に必要なモジュールのインポートと出力をマークダウンに変換する関数を定義します。そして、上で取得したAPIキーも設定します。最後にモデルの定義をしていきます。
```python
import google.generativeai as genai
import textwrap
from IPython.display import Markdown
```
```python
# マークダウンに出力を変換
def to_markdown(text):
  text = text.replace('•', '  *')
  return Markdown(textwrap.indent(text, '> ', predicate=lambda _: True))
```
```python
# ######で自分のAPIキーを入力
genai.configure(api_key="######")
```

```python
# モデルの定義
model = genai.GenerativeModel('gemini-pro')
```
モデルに関しては2023/12/20現在、'**gemini-pro**','**gemini-pro-vision**'の２つだけが使用できる状態なので、この２つのモデルで試してみます。ここまでで基本的な準備は整いました。

### 一般的な質問を聞いてみる
普段ChatGPTに聞いているように一般的な質問を投げてみます。東京とニューヨークについて聞いてみました。
```python
# 入力
response = model.generate_content("東京はどんな都市ですか？また、ニューヨークはどんな都市ですか？")
to_markdown(response.text)
```

```
# 出力
東京
・日本で最も人口の多い都市であり、世界で最も人口の多い都市圏の一つである。
・千代田区、中央区、港区など、多くの政府機関や企業の本部が集中している。
・後楽園、東京ドーム、神宮球場など、スポーツ施設が多い。
・東京ディズニーランド、東京ディズニーシーなど、レジャー施設が多い。
・伝統的な日本文化が色濃く残るエリアと、近代的なビルが立ち並ぶエリアが混在している。

ニューヨーク
・世界で最も多くの人が住む都市であり、世界で最も重要な都市の一つである。 
・マンハッタン、ブルックリン、クイーンズ、ブロンクス、スタテンアイランドの5つの行政区で構成されている。
・国連本部など、多くの国際機関が所在している。
・ウォール街は、金融の中心地として知られている。
・ブロードウェイは、世界有数の人気観光地である。
・多民族都市であり、様々な文化が混在している。
```
東京ディズニーランド、東京ディズニーシーが東京にあるという間違い以外は特に気になるところはありません。
ちなみに時間をおいてもう一度同じプロンプトを投げたら違う出力結果が得られました。

```
# 出力
東京
・人口：1,393万人（2020年）
・面積：2,193.96平方キロメートル
・位置：日本の関東地方に位置する。
・気候：温暖湿潤気候。夏は高温多湿、冬は乾燥している。
・経済：世界有数の大都市であり、金融、製造業、商業、観光業などさまざまな産業が盛んである。
・文化：伝統的な日本文化と近代的な西洋文化が融合しており、多様な文化が共存している。
・観光：東京タワー、スカイツリー、東京駅、皇居、築地市場、浅草寺、上野動物園、国立新美術館など、多くの観光スポットがある。

ニューヨーク
・人口：880万人（2020年）
・面積：1,214.4平方キロメートル
・位置：アメリカの東海岸に位置する。
・気候：温暖湿潤気候。夏は高温多湿、冬は乾燥している。
・経済：世界有数の大都市であり、金融、製造業、商業、観光業などさまざまな産業が盛んである。
・文化：多様な人種や民族が暮らしており、多様な文化が共存している。
・観光：自由の女神、エンパイアステートビル、タイムズスクエア、セントラルパーク、メトロポリタン美術館、アメリカ自然史博物館など、多くの観光スポットがある。
```
出力の仕方が結構変わっているので常に学習しているのかわかりませんが、情報が2020年からきているのでProだと最新情報で出力を出すのが難しいかもしれません。
試してみるとわかりますが、GeminiProはGPT-3.5などと比べるとより説明的な感じで、冗談を言うみたいなプロンプトは苦手な印象です。

### リファクタリングさせてみた
前回の記事でpandasとpolarsについて書いたのですが、それをGeminiで試します。
試しにこんなプロンプトを雑に投げてみました。

```python
# 入力
response = model.generate_content("""次のpandasの処理をpolarsで書き換えてください。
previous_loan_counts_pd = bureau_pd.groupby('SK_ID_CURR', as_index=False)['SK_ID_BUREAU'].count().rename(columns={'SK_ID_BUREAU': 'previous_loan_counts'}))`"""
)
```

```python
# 出力
import polars as pl

bureau_pl = pl.read_csv("bureau.csv")

previous_loan_counts_pl = bureau_pl.groupby(
    "SK_ID_CURR", maintain_order=False
).agg(
    pl.count("SK_ID_BUREAU").alias("previous_loan_counts")
)
```
しっかりリファクタリングしてくれてます。しかし、現在のpolarsのバージョンだとgroupbyがgroup_byになるので最新の書き方が反映されてないのは注意です。
ただ、抽象的な内容よりもコーディングとかはLLMはやはり強いです。GPT-3.5と比べても遜色ない感じでした。より複雑になるとGPTの方が強いかもしれないという印象もあります。

### テキスト要約をさせてみた
ニュースの要約もさせていきます。下記のニュース記事を要約してもらうようにプロンプトを投げてみます。
```
# 入力記事
インフルエンザが全国で猛威を振るっている。現在、二つのタイプのA型ウイルスが同時に流行しており、「一度かかったから大丈夫」とは安心できない。年末年始は人が集まる機会も多く、手洗いやマスクの着用など基本的な感染対策が求められる。

9月から異例の流行　インフルエンザ、いつまで？

　国立感染症研究所によると、全国約5000の定点医療機関から報告されたインフルエンザの感染者数（4～10日）が、1医療機関あたり30人を超え、警報レベルに達した。過去10年で最も早い。10日までの1週間に受診した患者数は約112万人と推計される。

新型コロナウイルス感染症のパンデミック（世界的大流行）の影響で、インフルエンザの流行は低い水準で推移していたが、2022年末に3年ぶりに流行入り。例年、流行は春ごろに収束するが、今年は流行の目安となる定点医療機関あたり「1人」を下回らないまま8月下旬に増加に転じた。

　現在の流行の特徴は、二つのタイプのインフルエンザA型が同時に拡大していることだ。感染研によると、直近5週間はA香港型と呼ばれる「AH3亜型」が60％、09年に新型インフルエンザとしてパンデミックを起こした「AH1pdm09」が37％を占める。

　過去10年で流行のピークが最も大きかった18年から19年のシーズンも、二つのタイプの同時流行が起きていた。

　インフルエンザに感染すると、そのウイルスのタイプに対する免疫はできるが、別のタイプに感染する可能性はあり、感染対策を続けることが大切だ。厚生労働省はホームページで、人混みを避け、外出後の手洗いや部屋の湿度を保ちこまめに換気することなどを呼びかけている。
```
<br>

```
# 出力
・インフルエンザが全国で流行しており、定点医療機関あたりの感染者数は警報レベルに達している。

・インフルエンザの感染者数は、新型コロナウイルスのパンデミックの影響で低い水準で推移していたが、2022年末に3年ぶりに流行入りした。

・今年の流行の特徴は、二つのタイプのインフルエンザA型が同時に拡大していることである。

・インフルエンザに感染すると、そのウイルスのタイプに対する免疫はできるが、別のタイプに感染する可能性があるため、感染対策を続けることが大切である。

・厚生労働省は、人混みを避け、外出後の手洗いや部屋の湿度を保ちこまめに換気することなどを呼びかけている。
```
ニュースの要約もできていますね。元々ニュース記事も短いのであまり要約できている感じはしませんが、要点をわかりやすくまとめてくれてますね。

### 画像を説明させてみた

Geminiでは画像認識とLLMを組み合わせたモデルも存在します。画像を読み込ませて説明するところをやってみます。使用する画像は内閣府が出している日本の経済成長率の推移グラフです。これを特に説明文は渡さずにこのまま渡して説明してくれるかをみていきます。
![4400.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707936/222bdc7b-16c6-f2e8-3ffa-2eebacd671ed.png)

モデルをGeminipro-visionに切り替えます。
```python
model = genai.GenerativeModel('gemini-pro-vision')
```
さらに画像を準備しておきます。ドライブに入れておいてpythonで読み込んでモデルに渡します。
```python
from PIL import Image
img = Image.open('/path/image.png')
```
プロンプトと同じように画像をモデルに渡して出力
```python
response = model.generate_content(img)
to_markdown(response.text)
```
すると以下のような出力が得られました。
```
# 出力
このグラフは、日本経済の成長率の推移を表しています。
１９７４年から２０２１年までの日本の経済成長率は、平均で４．２％でした。
しかし、１９９０年代以降は、経済成長率が低下し、２０１０年代にはマイナス成長となる年もありました。
これは、少子高齢化やグローバル化など、日本経済が直面している課題を反映しています。
```
回答の内容はあっさり目ですが、画像内だけで結構説明してくれているようです。特に設定していなくても日本語で回答をくれます。ちなみにプロンプトと一緒に渡すこともできるので、それも試してみます。

```python
prompt = "画像と一緒に投げるプロンプトを入力"
response = model.generate_content([prompt, img])
to_markdown(response.text)
```
画像から得られる情報をできるだけ詳細にまとめてください。と言うプロンプトを先ほどの画像を入力とともに渡した出力は以下のとおりです。

```
#　出力
このグラフは日本における経済成長率の推移を表しています。
横軸は年号、縦軸は経済成長率を示しています。
１９５５年から２０２１年までのデータが示されています。

１９５５年から１９７３年までは高度経済成長期で、平均成長率は９．１％でした。
１９７４年から１９９０年までは オイルショックやバブル経済崩壊などの影響で、
平均成長率は４．２％に低下しました。
１９９１年から２０２１年までは、平均成長率は０．８％とさらに低下しました。

このグラフから、日本経済は高度経済成長期からバブル期までは右肩上がりに成長していたが、
バブル崩壊後は低迷が続いていることがわかります。
```



## GeminiProの料金 ##
geminiは従量課金制になるようで、2024年以降の料金としては、
### 入力
1000文字あたり、0.00025ドル
画像一枚あたり、0.0025ドル

### 出力
1000文字あたり、0.0005ドル

となっています。

Gemini Ultraについてはまだ情報がありません。Proよりも上のグレードということがわかっているくらいでまだ公開もされていませんでした。これもGPT-4のように月額＋従量課金ということになるかもしれません。

ちなみにChatGPTの利用料金は下記の表のとおりです。

### ChatGPT利用料金
| model | Input（1,000トークンあたり） | Output（1,000トークンあたり） | 例：Input 1000トークン、Output 1000トークンの場合 |
| ---- | ---- | ---- | ---- | 
| GPT-4 8K | $0.03 | $0.06 | $0.09 |
| GPT-4 32K | $0.06 | $0.12 | $0.18 |
| GPT-3.5 Turbo 4K | $0.0015 | $0.002 | $0.0035 |
| GPT-3.5 Turbo 16K | $0.003 | $0.004 | $0.007 |

GPT-4に関してはこれに月額料金が発生します。
モデル精度を比較しないとなんとも言えませんが、geminiの方が安く使えるような印象を受けます。

 ## LangChainでも使える！！

 https://twitter.com/LangChainAI/status/1734982565352845428?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1734982565352845428%7Ctwgr%5E7795cada40801643c7561b2e167a65ffbf31d671%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fqiita.com%2Fembed-contents%2Ftweetqiita-embed-content__6eeb6c8def6273381af91a91b845279b


 APIが公開されたばかりですが、LangChainでもgeminiが使用できるようになっているみたいです。
 対応が早いのは素晴らしいです。これを使えばGeminiでも気になった情報が少し前だったり、長いテキストに対応できるようになったりと拡張することは可能なようです。

 ## まとめ・所感
GeminiProの良いところも悪いところをまとめると下記のようになります。
良いところ
- LLMとしてはまあまあ使えそう
- 画像には強そう
- コスパは良い（このままの料金設定なら）
- APIキーが発行できれば簡単に使える

気になるところ
- 出力の内容が安定してなさそう（結構変わることがある）
- コーディングとかはGPTの方が強いかも

全体的な使い勝手や精度という意味で言うと、今さらに色々な機能を追加したGPT-4を使う方が良いかもしれません。ただ、手軽にLLMをプロダクトに組み込むと言うことならGeminiは今後使う余地はあるかもしれません。
何よりもコストは抑えられそうなので、LLM導入を検討する材料にはなりそうです。