Maximofn commited on
Commit
8e2c98e
·
1 Parent(s): 6fdc750

First commit

Browse files
Files changed (5) hide show
  1. .gitignore +44 -0
  2. Dockerfile +16 -0
  3. README.md +88 -6
  4. app.py +114 -0
  5. requirements.txt +9 -0
.gitignore ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Archivos de entorno
2
+ .env
3
+ .env.*
4
+
5
+ # Archivos de Python
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+ *.so
10
+ .Python
11
+ env/
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # Directorios virtuales
28
+ venv/
29
+ ENV/
30
+ env/
31
+
32
+ # Archivos de IDE
33
+ .idea/
34
+ .vscode/
35
+ *.swp
36
+ *.swo
37
+
38
+ # Logs
39
+ *.log
40
+ logs/
41
+
42
+ # Archivos temporales
43
+ .DS_Store
44
+ Thumbs.db
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.13-slim
2
+
3
+ RUN useradd -m -u 1000 user
4
+ WORKDIR /app
5
+
6
+ COPY --chown=user ./requirements.txt requirements.txt
7
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
8
+
9
+ COPY --chown=user . /app
10
+
11
+ EXPOSE 7860
12
+
13
+ RUN --mount=type=secret,id=HUGGINGFACE_TOKEN,mode=0444,required=true \
14
+ test -f /run/secrets/HUGGINGFACE_TOKEN && echo "Secret exists!"
15
+
16
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,12 +1,94 @@
1
  ---
2
- title: SmolLM2 Backend LocalModel
3
- emoji: 👁
4
- colorFrom: red
5
- colorTo: blue
6
  sdk: docker
7
  pinned: false
8
  license: apache-2.0
9
- short_description: 'SmolLM2 Backend - FastAPI, Langchain and Docker. LLM local '
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: SmolLM2 Backend Local Model
3
+ emoji: 📊
4
+ colorFrom: yellow
5
+ colorTo: red
6
  sdk: docker
7
  pinned: false
8
  license: apache-2.0
9
+ short_description: Backend of SmolLM2 chatbot with local model
10
+ app_port: 7860
11
  ---
12
 
13
+ # SmolLM2 Backend Local Model
14
+
15
+ This project implements a FastAPI API that uses LangChain and LangGraph to generate text with the Qwen2.5-72B-Instruct model from HuggingFace.
16
+
17
+ ## Configuration
18
+
19
+ ### In HuggingFace Spaces
20
+
21
+ This project is designed to run in HuggingFace Spaces. To configure it:
22
+
23
+ 1. Create a new Space in HuggingFace with SDK Docker
24
+ 2. Configure the `HUGGINGFACE_TOKEN` or `HF_TOKEN` environment variable in the Space configuration:
25
+ - Go to the "Settings" tab of your Space
26
+ - Scroll down to the "Repository secrets" section
27
+ - Add a new variable with the name `HUGGINGFACE_TOKEN` and your token as the value
28
+ - Save the changes
29
+
30
+ ### Local development
31
+
32
+ For local development:
33
+
34
+ 1. Clone this repository
35
+ 2. Create a `.env` file in the project root with your HuggingFace token:
36
+ ```
37
+ HUGGINGFACE_TOKEN=your_token_here
38
+ ```
39
+ 3. Install the dependencies:
40
+ ```
41
+ pip install -r requirements.txt
42
+ ```
43
+
44
+ ## Local execution
45
+
46
+ ```bash
47
+ uvicorn app:app --reload
48
+ ```
49
+
50
+ The API will be available at `http://localhost:7860`.
51
+
52
+ ## Endpoints
53
+
54
+ ### GET `/`
55
+
56
+ Welcome endpoint that returns a greeting message.
57
+
58
+ ### POST `/generate`
59
+
60
+ Endpoint to generate text using the language model.
61
+
62
+ **Request parameters:**
63
+ ```json
64
+ {
65
+ "query": "Your question here",
66
+ "thread_id": "optional_thread_identifier"
67
+ }
68
+ ```
69
+
70
+ **Response:**
71
+ ```json
72
+ {
73
+ "generated_text": "Generated text by the model",
74
+ "thread_id": "thread identifier"
75
+ }
76
+ ```
77
+
78
+ ## Docker
79
+
80
+ To run the application in a Docker container:
81
+
82
+ ```bash
83
+ # Build the image
84
+ docker build -t smollm2-backend .
85
+
86
+ # Run the container
87
+ docker run -p 7860:7860 --env-file .env smollm2-backend
88
+ ```
89
+
90
+ ## API documentation
91
+
92
+ The interactive API documentation is available at:
93
+ - Swagger UI: `http://localhost:7860/docs`
94
+ - ReDoc: `http://localhost:7860/redoc`
app.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from pydantic import BaseModel
3
+ from huggingface_hub import InferenceClient
4
+
5
+ from langchain_core.messages import HumanMessage, AIMessage
6
+ from langgraph.checkpoint.memory import MemorySaver
7
+ from langgraph.graph import START, MessagesState, StateGraph
8
+
9
+ import os
10
+ from dotenv import load_dotenv
11
+ load_dotenv()
12
+
13
+ # HuggingFace token
14
+ HUGGINGFACE_TOKEN = os.environ.get("HUGGINGFACE_TOKEN", os.getenv("HUGGINGFACE_TOKEN"))
15
+
16
+ # Initialize the HuggingFace model
17
+ model = InferenceClient(
18
+ model="Qwen/Qwen2.5-72B-Instruct",
19
+ api_key=os.getenv("HUGGINGFACE_TOKEN")
20
+ )
21
+
22
+ # Define the function that calls the model
23
+ def call_model(state: MessagesState):
24
+ """
25
+ Call the model with the given messages
26
+
27
+ Args:
28
+ state: MessagesState
29
+
30
+ Returns:
31
+ dict: A dictionary containing the generated text and the thread ID
32
+ """
33
+ # Convert LangChain messages to HuggingFace format
34
+ hf_messages = []
35
+ for msg in state["messages"]:
36
+ if isinstance(msg, HumanMessage):
37
+ hf_messages.append({"role": "user", "content": msg.content})
38
+ elif isinstance(msg, AIMessage):
39
+ hf_messages.append({"role": "assistant", "content": msg.content})
40
+
41
+ # Call the API
42
+ response = model.chat_completion(
43
+ messages=hf_messages,
44
+ temperature=0.5,
45
+ max_tokens=64,
46
+ top_p=0.7
47
+ )
48
+
49
+ # Convert the response to LangChain format
50
+ ai_message = AIMessage(content=response.choices[0].message.content)
51
+ return {"messages": state["messages"] + [ai_message]}
52
+
53
+ # Define the graph
54
+ workflow = StateGraph(state_schema=MessagesState)
55
+
56
+ # Define the node in the graph
57
+ workflow.add_edge(START, "model")
58
+ workflow.add_node("model", call_model)
59
+
60
+ # Add memory
61
+ memory = MemorySaver()
62
+ graph_app = workflow.compile(checkpointer=memory)
63
+
64
+ # Define the data model for the request
65
+ class QueryRequest(BaseModel):
66
+ query: str
67
+ thread_id: str = "default"
68
+
69
+ # Create the FastAPI application
70
+ app = FastAPI(title="LangChain FastAPI", description="API to generate text using LangChain and LangGraph")
71
+
72
+ # Welcome endpoint
73
+ @app.get("/")
74
+ async def api_home():
75
+ """Welcome endpoint"""
76
+ return {"detail": "Welcome to FastAPI, Langchain, Docker tutorial"}
77
+
78
+ # Generate endpoint
79
+ @app.post("/generate")
80
+ async def generate(request: QueryRequest):
81
+ """
82
+ Endpoint to generate text using the language model
83
+
84
+ Args:
85
+ request: QueryRequest
86
+ query: str
87
+ thread_id: str = "default"
88
+
89
+ Returns:
90
+ dict: A dictionary containing the generated text and the thread ID
91
+ """
92
+ try:
93
+ # Configure the thread ID
94
+ config = {"configurable": {"thread_id": request.thread_id}}
95
+
96
+ # Create the input message
97
+ input_messages = [HumanMessage(content=request.query)]
98
+
99
+ # Invoke the graph
100
+ output = graph_app.invoke({"messages": input_messages}, config)
101
+
102
+ # Get the model response
103
+ response = output["messages"][-1].content
104
+
105
+ return {
106
+ "generated_text": response,
107
+ "thread_id": request.thread_id
108
+ }
109
+ except Exception as e:
110
+ raise HTTPException(status_code=500, detail=f"Error al generar texto: {str(e)}")
111
+
112
+ if __name__ == "__main__":
113
+ import uvicorn
114
+ uvicorn.run(app, host="0.0.0.0", port=7860)
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ requests
4
+ pydantic>=2.0.0
5
+ langchain
6
+ langchain-huggingface
7
+ langchain-core
8
+ langgraph > 0.2.27
9
+ python-dotenv