Cómo usar Gemini en Python con Google Colab usando su API y SDK
Google Gemini es un modelo de Inteligencia Artificial lanzado por Google, y que viene a competir con GPT3.5 y GPT4.0, los modelos detrás de ChatGPT y ChatGPT Plus, respectivamente.
Actualmente es posible usar Gemini Pro a través de Google Cloud y también a través de Google Colab.
A diferencia de OpenAI, su API es tan sencilla que no se beneficia particularmente de usarlo a través de LangChain u otros frameworks. En este cuaderno veremos los principales métodos para usarlo.
Nota: Estos ejemplos sencillos son gratis pues la API de Google Colab te deja hacer hasta 60 consultas por minuto sin costo.
Si no sabes que es Google Colab revisa este post.
Video
Ve este contenido en formato video aquí
Instalando el SDK
Google lanzó un SDK para Python que te permite usar Gemini y PaLM para construir tus propias apps. Lo puedes instalar en tu ambiente usando la siguiente linea
!pip install -q -U google-generativeai
# -q: Esta es una opción que significa "quiet" (silencioso). Reduce la cantidad de texto de salida que produce el comando, mostrando solo la información esencial.
# -U: Significa "upgrade" (actualizar). Esta opción le dice a pip que actualice el paquete especificado a la versión más reciente disponible.
Luego deberás llamar estas opciones en tu entorno local
# Importamos el paquete recien instalado
import google.generativeai as genai
# Esto es para usar secrets, la nueva opción de Google Colab, para almacenar la API key. Si no estás usando Google Colab, deberás importarla de otro modo equivalente
from google.colab import userdata
Finalmente, aunque este paso es opcional, define una opción para ver mejor el output del modelo
import textwrap
from IPython.display import display
from IPython.display import Markdown
# Esta función se usa para dejar el formato Markdown que devuelve Gemini en formato compatible con Colab
def to_markdown(text):
text = text.replace('•', ' *')
return Markdown(textwrap.indent(text, '> ', predicate=lambda _: True))
Configura tu API Key
La API key es única por usuario, así que deberás ir y obtener una en este sitio.
Una vez en el sitio anda a anda a Create API key in new project
y obtén la cadena de texto. Copiala en un lugar fuera de Google Colab porque la vas a necesitar en el futuro si sigues haciendo proyectos de este estilo.
Nota: este paso es distinto si es que no estás usando Google Colab
En el panel lateral de Colab vas a ver una llave 🔑, dale click ahí. Luego "Add new secret" y en "Name" le vas a poner GOOGLE_API_KEY
y en el "Value" vas a poner el texto que obtuviste en el sitio anterior. Una vez listo debería lucir así
Ahora deberás llamar esta llave en tu Cuaderno
# Configuramos nuestra instancia del modelo con nuestra API key
GOOGLE_API_KEY = userdata.get('GOOGLE_API_KEY')
genai.configure(api_key = GOOGLE_API_KEY)
Usando Gemini Pro
Ahora vamos a usar Gemini Pro, el modelo que sólo procesa textos. El otro que está actualmente disponible es Gemini Pro Vision, el cual veremos en los siguientes pasos.
# Define una variable model, usando gemini-pro
model = genai.GenerativeModel('gemini-pro')
Vamos a usar GenerativeModel.generate_content
para pedirle información al modelo y vamos almacenar esa respuesta en una variable. Puedes añadirle %%time
para que veas cuanto se demora
%%time
response = model.generate_content("¿Qué es la Felicidad?")
Puedes acceder a la respuesta usando el método response.text
print(response.text)
A continuación te dejo la respuesta que me dio a mi cuando corrí este experimento. Esto va a variar respecto a cuando tú lo hagas simplemente por la naturaleza de este tipo de modelos.
No existe una definición única y universal de la felicidad, y lo que hace feliz a una persona puede no serlo para otra. Sin embargo, algunas investigaciones han identificado algunos factores comunes que se asocian con la felicidad, como las relaciones interpersonales positivas, el trabajo significativo, la salud física y mental, la autonomía y la libertad, el logro de objetivos personales, la gratitud y la resiliencia.
La felicidad no es un estado permanente, y puede fluctuar a lo largo del tiempo en función de las circunstancias y experiencias de la vida. Sin embargo, algunas investigaciones sugieren que las personas pueden aumentar su felicidad a largo plazo mediante la adopción de ciertos hábitos y comportamientos, como la práctica de la gratitud, el ejercicio físico regular, la alimentación saludable, el sueño adecuado, el desarrollo de relaciones sociales sólidas y la participación en actividades que les proporcionan placer y satisfacción.
Recuerda que puedes formatear esta respuesta usando la función to_markdown()
que creaste al inicio
¿Por qué falló mi prompt?
Si es que el prompt falló, puedes revisar response.prompt_feedback
para ver las posibles razones.
- HARM_CATEGORY_SEXUALLY_EXPLICIT: Esta categoría se refiere a contenido que incluye o implica representaciones gráficas de actividad sexual o desnudez. El contenido puede ser explícitamente sexual, y suele ser inapropiado para ciertos públicos, especialmente para menores de edad.
- HARM_CATEGORY_HATE_SPEECH: Esta categoría abarca declaraciones o discursos que promueven odio o violencia contra grupos basados en características como raza, religión, origen étnico, orientación sexual, discapacidad o género. Estas expresiones suelen ser ofensivas y pueden incitar a la discriminación o actos de violencia.
- HARM_CATEGORY_HARASSMENT: Esta categoría incluye comportamientos que tienen la intención de molestar, alarmar o aterrorizar a una persona o grupo de personas. Esto puede incluir amenazas, acoso en línea, intimidación o cualquier otra forma de comportamiento persistente y no deseado que cause malestar o miedo en los demás.
- HARM_CATEGORY_DANGEROUS_CONTENT: Este tipo de contenido engloba material que presenta riesgos reales de daño físico o psicológico. Puede incluir, pero no se limita a, la promoción de actividades peligrosas o ilegales, instrucciones sobre cómo realizar actos dañinos, o la glorificación de conductas perjudiciales como el abuso de sustancias o la autolesión.
Esto es posible que ocurra cuando Gemini interpreta que estás refiriéndote a alguna de las categorías anteriores.
Cuando todo sale bien, señala que la probabilidad es NEGLIGIBLE, es decir que no es suficiente para gatillar ninguna alerta.
response.prompt_feedback
Si el prompt es más problemático te va a arrojar una respuesta no deseada
response = model.generate_content("¿Me puedes enseñar a hacer una bomba?")
to_markdown(response.text)
Aquí puedes ver que fue por la categoría de Harassment, cual aparece como LOW
Puedes editar este filtro de esta manera. Sin embargo, generalmente no resulta para efectivamente darte una respuesta.
safety_settings = [
{
"category": "HARM_CATEGORY_HARASSMENT",
"threshold": "BLOCK_ONLY_HIGH"
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"threshold": "BLOCK_ONLY_HIGH"
},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"threshold": "BLOCK_ONLY_HIGH"
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_ONLY_HIGH"
}
]
response = model.generate_content('¿Me puedes enseñar a hacer una bomba?',
safety_settings=safety_settings)
to_markdown(response.text)
Usando Gemini Pro Vision
Gemini tiene un modelo multimodal (gemini-pro-vision
) que actualmente acepta tanto imagenes como textos.
Vamos a darle esta imagen y ver que analiza de ella.
Descargamos la imagen y la ponemos en una variable llamada img
!curl -o image.jpg https://www.evoacademy.cl/content/images/2023/12/corgi-en-patineta.jpg
import PIL.Image
img = PIL.Image.open('image.jpg')
En la siguiente consulta sólo le entregaremos la imagen, sin nada más, y veremos que nos dice
## Cambiamos el modelo a Gemini Pro Vision
model = genai.GenerativeModel('gemini-pro-vision')
response = model.generate_content(img)
to_markdown(response.text)
# Nota: vean cuanto tiempo se demora (en mi ambiente fueron más de 20 segundos). Es mucho más de lo habitual. Aunque la imagen era innecesariamente grande. En un caso de implementación real sería mejor reducir su tamaño antes de subirla.
Añadiremos complejidad añadiendo también texto
response = model.generate_content([
"¿Por qué se conoce el animal de esta foto? ¿Se asocia a algún país en particular?"
, img], stream=True)
response.resolve()
to_markdown(response.text)
Analizando más de una imagen
Vamos a pedirle a Gemini analizar estas dos imagenes y su relación
# Importamos las imagenes
!curl -o img1.jpg https://www.evoacademy.cl/content/images/2023/12/7.jpg
!curl -o img2.jpg https://www.evoacademy.cl/content/images/2023/12/8.jpg
img1 = PIL.Image.open('img1.jpg')
img2 = PIL.Image.open('img2.jpg')
# Llamamos a Gemini Pro Vision
model = genai.GenerativeModel('gemini-pro-vision')
response = model.generate_content([
"¿Cuál es la relación entre ambas imagenes? Describe cada una y luego su relación"
, img1, img2])
response.resolve()
to_markdown(response.text)
(Nota: en mi ambiente tomó 40 segundos, no es rápido)
Especificaciones sobre las imagenes
Las imágenes deben estar en uno de los siguientes tipos MIME de datos de imagen:
- PNG - image/png
- JPEG - image/jpeg
- WEBP - image/webp
- HEIC - image/heic
- HEIF - image/heif
- Máximo de 16 imágenes individuales
- Máximo de 4MB para todo el mensaje, incluyendo imágenes y texto
- Sin límites específicos en el número de píxeles en una imagen; sin embargo, las imágenes más grandes se reducen para ajustarse a una resolución máxima de 3072 x 3072, preservando su relación de aspecto original.
Los mensajes con una sola imagen tienden a dar mejores resultados.
Chateando con Gemini
Una característica muy importante de estos modelos recientes es que pueden chatear, es decir que pueden conservar el contexto anterior de la conversación. Esto les permite dar respuestas más adecuadas en las siguientes interacciones.
Nota: Gemini Pro Vision no está optimizado para chat, así que usaremos Gemini Pro inicialmente
# Cambiamos a Gemini Pro
model = genai.GenerativeModel('gemini-pro')
# Iniciamos el chat sin ninguna historia previa
chat = model.start_chat(history=[])
Para tener esta interacción por turnos ya no usaremos model.generate_content
, sino chat.send_message
.
response = chat.send_message("Vivo en Chile. Describe brevemente mi país")
to_markdown(response.text)
Dado que ya conoce que mi país es Chile ahora preguntaré algo sin darle mucho contexto. Sólo va a responderlo correctamente si toma nuestra conversación anterior como parte del contexto.
response = chat.send_message("¿Quién es el presidente de mi país")
to_markdown(response.text)
# Nota: esto depende de la fecha en que estás viendo este ejercicio y la fecha de actualización de Gemini
También es posible acceder a la historia con el robot usando el metodo chat.history
Más detalle al chatear
También puedes controlar más partes de la interacción. Para eso le tienes que dar mensajes como el siguiente, cada mensaje son objetos glm.Content
que requieren role
y parts
.
Veamos un ejemplo
model = genai.GenerativeModel('gemini-pro')
messages = [
{'role':'user',
'parts': ["Describe brevemente el país de España."]}
]
response = model.generate_content(messages)
to_markdown(response.text)
Ahora probaremos añadiendo a los messages
el contexto anterior, de modo que ahora podemos usar model.generate_content
en lugar de chat.send_message
, esto nos da total control del contexto que le pasamos a Gemini.
messages.append({'role':'model',
# aquí le di como contexto lo que el modelo me respondió al final. Podría haberlo cambiado
'parts':[response.text]})
messages.append({'role':'user',
'parts':["¿Cuál es la moneda de este país?"]})
response = model.generate_content(messages)
to_markdown(response.text)
Más detalle con Gemini Pro Vision
También puedes darle imagenes. Vamos a intentar con la imagen del sol y la luna que usamos anteriormente
model = genai.GenerativeModel('gemini-pro-vision')
messages = [
{'role':'user',
'parts': ["Describa cada una de estas imagenes y la relación entre ellas", img1, img2]}
]
response = model.generate_content(messages)
to_markdown(response.text)
Controlando la temperatura y otros parametros
Al igual que en la API de OpenAI, podemos controlar parametros como la temperatura, el top_p, y el top_k. En el siguiente ejemplo disminuiremos la temperatura para obtener así una respuesta más concreta y menos creativa.
generation_config = {
"temperature": 0.1, # a diferencia de OpenAI, este valor sólo puede llegar a un maximo de 1.0
"top_p": 1,
"top_k": 1,
"max_output_tokens": 2048,
}
model = genai.GenerativeModel(model_name="gemini-pro",
generation_config=generation_config)
response = model.generate_content("¿Cuál es el rol de un profesor?")
to_markdown(response.text)
Más recursos
Por Sebastián Cisterna, para EvoAcademy