caiocampos-hotmart commited on
Commit
244d22f
·
1 Parent(s): 73a52b2

Add application file

Browse files
Files changed (8) hide show
  1. .gitignore +4 -0
  2. Dockerfile +13 -0
  3. README.md +53 -4
  4. app.py +74 -0
  5. docs/application.md +78 -0
  6. docs/oficial_docs.txt +3 -0
  7. main.py +106 -0
  8. requirements.txt +5 -0
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ *.gguf
2
+ models/*
3
+ __pycache__/
4
+ .env
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ RUN useradd -m -u 1000 user
4
+ USER user
5
+ ENV PATH="/home/user/.local/bin:$PATH"
6
+
7
+ WORKDIR /app
8
+
9
+ COPY --chown=user ./requirements.txt requirements.txt
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
+
12
+ COPY --chown=user . /app
13
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,11 +1,60 @@
1
  ---
2
- title: Llm Agent Api
3
- emoji: 🌍
4
  colorFrom: blue
5
- colorTo: gray
6
  sdk: docker
 
7
  pinned: false
8
  license: mit
 
9
  ---
10
 
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: LLM Agent API
3
+ emoji: 🧠
4
  colorFrom: blue
5
+ colorTo: purple
6
  sdk: docker
7
+ app_port: 7860
8
  pinned: false
9
  license: mit
10
+ hardware: cpu-upgrade
11
  ---
12
 
13
+ # 🧠 LLM Agent API
14
+
15
+ API REST com modelo Llama 2 7B rodando localmente usando llama-cpp-python.
16
+
17
+ ## Endpoints
18
+
19
+ ### POST /chat
20
+ Envia mensagem para o agente LLM.
21
+
22
+ **Request:**
23
+ ```json
24
+ {
25
+ "message": "Olá, como você está?",
26
+ "max_tokens": 100,
27
+ "temperature": 0.7
28
+ }
29
+ ```
30
+
31
+ **Response:**
32
+ ```json
33
+ {
34
+ "response": "Olá! Estou bem, obrigado por perguntar. Como posso ajudá-lo hoje?"
35
+ }
36
+ ```
37
+
38
+ ### GET /health
39
+ Verifica status da API.
40
+
41
+ **Response:**
42
+ ```json
43
+ {
44
+ "status": "healthy"
45
+ }
46
+ ```
47
+
48
+ ## Como usar
49
+
50
+ ```bash
51
+ curl -X POST "http://localhost:7860/chat" \
52
+ -H "Content-Type: application/json" \
53
+ -d '{"message": "Olá!"}'
54
+ ```
55
+
56
+ ## Tecnologias
57
+
58
+ - FastAPI
59
+ - llama-cpp-python
60
+ - Uvicorn
app.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ from llama_cpp import Llama
4
+ from huggingface_hub import hf_hub_download
5
+ import os
6
+
7
+ app = FastAPI(title="LLM Agent API", version="1.0.0")
8
+
9
+ class ChatRequest(BaseModel):
10
+ message: str
11
+ max_tokens: int = 100
12
+ temperature: float = 0.7
13
+
14
+ class ChatResponse(BaseModel):
15
+ response: str
16
+
17
+ class LocalLLMAgent:
18
+ def __init__(self):
19
+ # Download do modelo se não existir
20
+ model_path = "./llama-2-7b-chat.Q4_K_M.gguf"
21
+
22
+ if not os.path.exists(model_path):
23
+ print("Baixando modelo...")
24
+ model_path = hf_hub_download(
25
+ repo_id="TheBloke/Llama-2-7B-Chat-GGUF",
26
+ filename="llama-2-7b-chat.Q4_K_M.gguf",
27
+ local_dir="./"
28
+ )
29
+ print("Modelo baixado com sucesso!")
30
+
31
+ self.llm = Llama(
32
+ model_path=model_path,
33
+ chat_format="llama-2",
34
+ n_ctx=2048,
35
+ verbose=False
36
+ )
37
+ self.messages = [
38
+ {"role": "system", "content": "Responda sempre em português brasileiro de forma natural e conversacional."}
39
+ ]
40
+
41
+ def chat(self, message: str, max_tokens: int = 100, temperature: float = 0.7) -> str:
42
+ self.messages.append({"role": "user", "content": message})
43
+
44
+ response = self.llm.create_chat_completion(
45
+ messages=self.messages,
46
+ max_tokens=max_tokens,
47
+ temperature=temperature
48
+ )
49
+
50
+ assistant_message = response['choices'][0]['message']['content']
51
+ self.messages.append({"role": "assistant", "content": assistant_message})
52
+
53
+ return assistant_message
54
+
55
+ # Inicializa o agente globalmente
56
+ agent = None
57
+
58
+ @app.on_event("startup")
59
+ async def startup_event():
60
+ global agent
61
+ agent = LocalLLMAgent()
62
+
63
+ @app.post("/chat", response_model=ChatResponse)
64
+ async def chat_endpoint(request: ChatRequest):
65
+ if agent is None:
66
+ return ChatResponse(response="Modelo ainda carregando, tente novamente.")
67
+ response = agent.chat(request.message, request.max_tokens, request.temperature)
68
+ return ChatResponse(response=response)
69
+
70
+ @app.get("/health")
71
+ async def health_check():
72
+ return {"status": "healthy"}
73
+
74
+ # Removido - uvicorn será executado pelo Dockerfile
docs/application.md ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🧠 Projeto: Aplicação Local para Rodar LLMs voltados para Agentes (CPU-Friendly)
2
+
3
+ ## 🎯 Objetivo
4
+
5
+ Desenvolver uma aplicação **simples, leve e de fácil entendimento**, capaz de rodar **modelos LLM localmente em CPU**, utilizando tecnologias como [`llama.cpp`](https://github.com/ggml-org/llama.cpp) e formatos como `GGUF`.
6
+
7
+ A aplicação será usada com **modelos ajustados para criação de agentes**, ou seja, com suporte a:
8
+
9
+ - Diálogo multi-turno
10
+ - Seguir instruções
11
+ - Raciocínio estruturado
12
+ - Suporte futuro ao uso de ferramentas (LangChain tools)
13
+
14
+ O foco inicial é **testar o modelo localmente**, sem deploy ainda.
15
+
16
+ ---
17
+
18
+ ## ✅ Requisitos
19
+
20
+ - Rodar **100% em CPU**, compatível com Hugging Face Spaces (Free Tier)
21
+ - Usar **modelos em formato GGUF**, leves, voltados para agentes
22
+ - Usar **llama-cpp-python** (binding oficial Python para llama.cpp)
23
+ - Código em Python, com estrutura clara, comentado e expansível
24
+ - Interface simples via terminal ou função Python
25
+
26
+ ---
27
+
28
+ ## 🧠 Modelos recomendados (GGUF)
29
+
30
+ Modelos ajustados para **conversação com agentes**:
31
+
32
+ | Modelo | Tamanho | Destaques |
33
+ | --------------------- | ------- | ----------------------------- |
34
+ | OpenHermes 2.5 GGUF | 7B | Muito bom com LangChain |
35
+ | Nous Hermes 2 Mistral | 7B | Fortemente instruído |
36
+ | TinyLlama Chat GGUF | 1.1B | Super leve, roda fácil em CPU |
37
+ | Zephyr 7B Beta GGUF | 7B | Instrução + estilo de chat |
38
+ | OpenChat 3.5 GGUF | 7B | Excelente para agentes |
39
+
40
+ ---
41
+
42
+ ## 🔧 Tecnologias a utilizar
43
+
44
+ - [llama.cpp](https://github.com/ggml-org/llama.cpp)
45
+ - [llama-cpp-python](https://github.com/abetlen/llama-cpp-python)
46
+ - Python 3.10+
47
+ - Modelo `.gguf` (baixado localmente)
48
+
49
+ ---
50
+
51
+ ## 🛑 Fora do escopo neste momento
52
+
53
+ - Deploy na nuvem (ex: Hugging Face Spaces)
54
+ - API REST / Chat API
55
+ - Integração com LangChain
56
+
57
+ Essas partes virão nas próximas fases do projeto.
58
+
59
+ ---
60
+
61
+ ## ✅ Output esperado nesta fase
62
+
63
+ - Aplicação local funcional
64
+ - Capaz de carregar e rodar um modelo `.gguf` leve
65
+ - Permitir conversas básicas (ex: terminal)
66
+ - Código simples, modular e pronto para expansão
67
+
68
+ ---
69
+
70
+ ## 📦 Próximo passo sugerido
71
+
72
+ Criar:
73
+
74
+ - `main.py` com execução local do modelo
75
+ - `requirements.txt`
76
+ - Documentação explicando como rodar
77
+
78
+ ---
docs/oficial_docs.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ llama-cpp-python: https://github.com/abetlen/llama-cpp-python
2
+ Modelo TinyLlama GGUF (TheBloke): https://huggingface.co/TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF
3
+ Integração LangChain com LlamaCpp: https://python.langchain.com/docs/integrations/llms/llamacpp/
main.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Aplicação Local para LLMs voltados para Agentes
5
+ Roda modelos GGUF localmente usando llama-cpp-python
6
+ """
7
+
8
+ from llama_cpp import Llama
9
+ import os
10
+ import sys
11
+
12
+ # Força encoding UTF-8
13
+ if sys.stdout.encoding != 'utf-8':
14
+ sys.stdout.reconfigure(encoding='utf-8')
15
+ if sys.stdin.encoding != 'utf-8':
16
+ sys.stdin.reconfigure(encoding='utf-8')
17
+
18
+ class LocalLLMAgent:
19
+ def __init__(self, n_ctx: int = 2048):
20
+ """
21
+ Inicializa o agente LLM local
22
+
23
+ Args:
24
+ n_ctx: Tamanho do contexto (tokens)
25
+ """
26
+ #llama-2-7b.Q2_K.gguf
27
+ model_path = "./models/llama-2-7b-chat.Q4_K_M.gguf"
28
+ print(f"Carregando modelo: {model_path}")
29
+ self.llm = Llama(
30
+ model_path=model_path,
31
+ chat_format="llama-2",
32
+ verbose=False
33
+ )
34
+ print("Modelo carregado com sucesso!")
35
+ # Inicializa com prompt do sistema em português
36
+ self.messages = [
37
+ {"role": "system", "content": "Responda sempre em português brasileiro de forma natural e conversacional."}
38
+ ]
39
+
40
+ def chat(self, user_message: str, max_tokens: int = 100, temperature: float = 0.7) -> str:
41
+ """
42
+ Gera resposta usando o formato de chat nativo
43
+
44
+ Args:
45
+ user_message: Mensagem do usuário
46
+ max_tokens: Máximo de tokens na resposta
47
+ temperature: Controle de criatividade (0.0 a 1.0)
48
+
49
+ Returns:
50
+ Resposta do modelo
51
+ """
52
+ # Adiciona mensagem do usuário
53
+ self.messages.append({"role": "user", "content": user_message})
54
+
55
+ # Gera resposta usando create_chat_completion conforme documentação
56
+ response = self.llm.create_chat_completion(
57
+ messages=self.messages,
58
+ max_tokens=max_tokens,
59
+ temperature=0.75
60
+ )
61
+
62
+ assistant_message = response['choices'][0]['message']['content']
63
+
64
+ # Adiciona resposta do assistente ao histórico
65
+ self.messages.append({"role": "assistant", "content": assistant_message})
66
+
67
+ return assistant_message
68
+
69
+ def main():
70
+ """Função principal - interface de terminal"""
71
+
72
+ print("🧠 Aplicação Local para LLMs Agentes")
73
+ print("=" * 40)
74
+
75
+ try:
76
+ agent = LocalLLMAgent()
77
+
78
+ print("\n🧠 Agente LLM Local iniciado!")
79
+ print("Digite 'sair' para encerrar\n")
80
+
81
+ while True:
82
+ try:
83
+ user_input = input("Você: ").strip()
84
+ except UnicodeDecodeError:
85
+ user_input = input("Voce: ").strip()
86
+
87
+ if user_input.lower() in ['sair', 'exit', 'quit']:
88
+ print("Encerrando...")
89
+ break
90
+
91
+ if not user_input:
92
+ continue
93
+
94
+ print("Agente: ", end="", flush=True)
95
+ response = agent.chat(user_input)
96
+ print(response)
97
+ print()
98
+
99
+ except Exception as e:
100
+ import traceback
101
+ print(f"Erro: {e}")
102
+ print("Detalhes do erro:")
103
+ traceback.print_exc()
104
+
105
+ if __name__ == "__main__":
106
+ main()
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ llama-cpp-python
2
+ huggingface-hub
3
+ fastapi
4
+ uvicorn
5
+ pydantic