This is the backend of the Jugend forscht 2023 project "Chatbot als Schülergehilfe: Sind Konsultationen mit Lehrern noch nötig?" ("Chatbot as a student helper: are consultations with teachers still necessary?"), entered in the Mathematik/Informatik category. Students ask a question in an iOS app. This REST API stores the question and answers it with a German GPT-2 language model fine-tuned for the project.
A team of two, Denys Shkola and Teodor Balla, built the project between December 2022 and March 2023 and entered it from Deutsche Schule Prag. Denys fine-tuned the model and wrote this backend and the SwiftUI iOS client; all commits in this repository are his.
Awards (Jugend forscht 2023):
- Regional round: 1st place and the c't Magazin special prize.
- Saxony-Anhalt state final: 2nd prize and the Carl Zeiss special prize Sonderpreis Digitalisierung.
SwiftUI iOS app ──HTTP/JSON──▶ Spring Boot REST API ──▶ python3 usage.py "<question>"
(JPA, H2 in-memory) (Transformers + TensorFlow,
fine-tuned dbmdz/german-gpt2)
- Stack: Spring Boot 3.0 and Java 17, Spring Web, Spring Data JPA with an in-memory H2 database, MapStruct DTO mappers and Lombok.
- Answering: for each new question,
AnswerServiceImplrunspython3 <script> "<question>"and stores the script's output as the answer. - Model:
usage.pyloads thedbmdz/german-gpt2tokenizer and TensorFlow model and adds the special tokens used in fine-tuning. It then loads the fine-tuned weights and generates up to 20 new tokens with a Hugging Facetext-generationpipeline. - iOS client: kept in a separate repository.
| Method | Path | Body | Returns |
|---|---|---|---|
| POST | /api/v1/users |
{"name": "..."} |
the new user and its user_url |
| GET | /api/v1/users/{id} |
none | the user with their questions and answers |
| GET | /api/v1/users/{id}/questions |
none | the user's questions and answers |
| POST | /api/v1/questions/users/{userId} |
{"body": "..."} |
{"answers": [{"body": "..."}]} |
You need JDK 17; the Maven wrapper is included. For this README, the build, the single context-load test and the four endpoints were checked with JDK 17.
./mvnw package
java -jar target/chatbot-0.0.1-SNAPSHOT.jar # listens on $PORT, default 5000
curl -X POST localhost:5000/api/v1/users \
-H 'Content-Type: application/json' -d '{"name": "Anna"}'
curl -X POST localhost:5000/api/v1/questions/users/1 \
-H 'Content-Type: application/json' -d '{"body": "Was ist eine Primzahl?"}'Without the model files, the second call stores the question and returns an empty answer. To generate real answers:
- Weights. The fine-tuned weights and the fine-tuning code are not in this repository. Put a TensorFlow checkpoint where
usage.pyloads it (placeholderMODEL-PATH). - Script path. Set the path to
usage.pyinAnswerServiceImpl(placeholderPATH). In the Docker image it is/usr/src/app/src/main/java/alphashk/chatbot/python/usage.py. - Python packages. Install the dependencies from
requirements.txt(TensorFlow 2.11.0, Transformers 4.26.1).
The Dockerfile builds on the tensorflow/tensorflow image and adds OpenJDK 17 and the Python requirements. It runs the jar from target/, so build the jar first. The app listens on $PORT (default 5000), not on the exposed port 8080, so pass -e PORT=8080 or publish port 5000. The image was not rebuilt for this README.
This is a competition prototype, and the code is unchanged since December 2023. It has one test (the Spring context loads) and no error handling: unknown IDs return HTTP 500.
More of Denys Shkola's work: alphashk.github.io