Reflections on My Second Software Engineering Internship as a Computer Science Junior at NUS
A multipart series where I reflect on my university opportunities- Junior Summer @ Sentient.io, Singapore
Author’s Note: About a month ago, during a conversation with my mentor from my current internship at the Government Technology Agency (GovTech), I was inspired to reflect on my various internship experiences. I believe this reflection could be valuable in helping me clarify what I want for my future and serve as a great way to document what I’ve learned from each experience.
And so begins this multipart series! I hope to go beyond just sharing my internship experiences and dive into other university and pre-university experiences as well.
Context
I joined Sentient.io during the summer of my second year as a Computer Science undergraduate at the National University of Singapore (NUS). I recall that after my second year at NUS, I was at a stage where I was pretty eager to learn. I think there are a couple of reasons behind this. Firstly, I regained my confidence in my technical capabilities and “life energy” during my second year at NUS, especially after a tiring second semester during my freshman year (perhaps I will write another post about this in the future). In addition, I felt like I was lacking a lot of “real-world” technical knowledge, as I was busy learning about theoretical concepts in school like networks, cybersecurity, and software engineering practices. Hence, I was eager to apply and use that knowledge.
I was really happy to be offered a role at Sentient.io, as my experience applying for my Year 2 summer internship was far from easy. Even though I had some experience to add to my resume from my first internship, I was missing a key ingredient — LeetCode. As a result, I was rejected by many opportunities because I couldn’t complete the online assessments or technical interviews. My optimistic and idealistic self lowered my internship expectations with each rejection. However, with a stroke of luck, I was offered a role at Sentient.io!
So, what does Sentient.io do? You can find out more from their website: Sentient.io, but in short, the way I would describe it is that Sentient.io is a company that empowers enterprises with intelligent AI solutions, driving exponential revenue growth and streamlining workflows. It is primarily a Business-to-Business (B2B) company, having collaborated with notable clients such as Mediacorp, Toyota, Brother, and more. Sentient.io aids in understanding the pain points of enterprises and leverages AI solutions to develop appropriate AI pipelines, which are then integrated into enterprise workflows to address these pain points. Additionally, Sentient.io offers an array of microservices for developers to utilize with ease.
What Did I Do?
I was employed as an Application Engineer intern (which is essentially a Software Engineer), and my original task was to assist the then tech lead in continuing to build and develop their flagship product, ScribeRabbit. However, due to some unforeseen circumstances, I mainly ended up working on tasks not related to ScribeRabbit. In short, I worked on the following projects:
Project 1: Demo Apps
My very first task at Sentient.io was to help build an Automatic Speech Recognition (ASR) demo application. Don’t worry, I wasn’t supposed to build the ASR model from scratch. I was tasked with trying to improve existing ASR models by integrating them with other ASR models or through the use of ChatGPT, which was relatively new back then.
Fortunately, I managed to complete it in three days using Next.js. This was a good warm-up exercise, as I was somewhat rusty with web development, having mainly done more theory-related assignments in school or building a desktop application with Java.
I learned two new technical things from this short project. The first was prompt engineering. The second was the use of Docker containers. I had previously used Docker, but my involvement was limited to starting and stopping containers. I didn’t truly understand its benefits. For this demo application, the DevOps team encountered deployment issues because we used a package called FFmpeg, which required users to download the binary file onto their laptops. To solve this, I created a Dockerfile and wrote the necessary code for setup. This allowed the DevOps team and other users to simply build and run the container without explicitly downloading the binary file onto the server machine first. And that’s when I finally understood an important benefit of Docker: containerization.
My most significant takeaway from this assignment wasn’t a technical skill, but rather a set of soft skills actually. When we first embarked on this project, I became focused in the engineering aspect of the task that I considered only how to expediently develop the web application. The project description was vague, and I failed to question who would be using the application, for whom we were creating the demo, or who would be maintaining the application in the long term. Hence, I chose to use Next.js, which I later discovered made it challenging for existing developers to adapt, as they were predominantly familiar with Vanilla JS, Vue.js, and FastAPI. So yup, I learned the importance of asking more probing questions to gain a clearer, broader understanding of a project, thereby enhancing its maintainability for future users!
Project 2: Private Large Language Model Prototype
This was the most difficult task I was assigned so far and the one I always use when asked, “Tell me about a time you worked on a technical project.” The end result is far from satisfactory, but I still take pride in it because it was almost entirely self-managed, self-learned, and self-driven. It also made me realize the importance of having a mentor.
Okay, so this project involved developing a private Large Language Model (LLM) that could be run locally on a self-managed server and trained on local data. This solution was intended for customers who prioritize data privacy and desire a custom-trained LLM. It was a great idea at the time, and I’ve seen this idea become very popular among startups recently. However, this project posed a huge challenge for me due to my lack of prior experience with LLMs and limited exposure to GPUs. Furthermore, the GPU was on a server managed by Huawei Cloud and accessible via a VM. As a result, I had to undertake extensive research and self-learning to work on this task.
This project felt more like research than engineering, as most of my time was devoted to studying LLMs, NLP, academic papers, and GPUs. I delved deeper into existing open-source LLM models such as LLaMA, Alpaca, and ChatGLM 6B, as well as strategies to optimize them so they could run on smaller VMs using quantization and LoRA. I was also introduced to HuggingFace, an excellent platform and service for fine-tuning models and learning more about NLP. Moreover, I used LangChain, a powerful tool that integrates multiple beneficial libraries to enhance the abilities of the LLM. LangChain (or, more accurately, RAG, which I later realized) was particularly enlightening because I initially thought that to “train” an LLM required fine-tuning the weights. However, I realized I could potentially use the original weights and simply query local documents.
Beyond LLM and NLP tools, I learned how to optimize my workflow. Since most of my work was executed on a VM on a server, considerable time was spent downloading or training the model. Hence, I utilized TMUX, a great tool that allowed me to train and disconnect from the VM without worrying that a disconnection would interrupt the training. Additionally, given that I primarily used the command line interface when using the VM, my proficiency with CLI commands improved, with Vim proving especially useful.
I am happy to report that I succeeded in running an open-source LLM on the VM. The LLM can query local documents via LangChain and can also be fine-tuned through self-instruction techniques. The final product is not complex or noteworthy, and with hindsight, it could perhaps have been achieved in a shorter time frame with more experience. This project spanned all three months and was ultimately handed over to existing developers to tailor it for a new client after being shown as a demo application for clients.
Project 3: ScribeRabbit
ScribeRabbit was a project that occupied the majority of my final month. ScribeRabbit is an online video editor powered by an AI transcribing model, which allows users to get their videos transcribed swiftly. Users can simply upload their video, and the system automatically generates transcribed text with the appropriate timestamps. Users then have the ability to review and edit any inaccuracies in the text. Additionally, ScribeRabbit enables users to manage multiple workspaces simultaneously, facilitating work on multiple projects.
This project was intriguing. As you may have noticed, I worked on many greenfield projects, such as prototypes, during my first two months at Sentient. The advantage of this was that it allowed me to explore and gain new exposure. However, the downside was that these projects were often smaller in scale, and I typically worked in much smaller teams (1–3 people), guided by advisors rather than tech leads. In contrast, ScribeRabbit is a functional project with a team of 8–10 individuals working on it. My primary role was to help extend their API functionalities for user authentication using FastAPI and Keycloak, as well as to rectify existing bugs to ensure proper triggering of their Argo workflows.
This project provided me with many exposure to new technical exposures. Firstly, I gained exposure to the microservice architecture and spent some time understanding how ScribeRabbit operates its various backend services using FastAPI, NATs.io, Argo workflows, and Kubernetes (which till this date I only roughly understand its functionality on a high level only). Observing a large-scale project and how its various components interdependently function was impressive. Secondly, given that this is a brownfield project, the codebase is significantly larger and spread across multiple code repositories. Hence, it was crucial to run several services locally and experiment with them to gain a better understanding of how things work.
Project 4: Company Website
At the start of my internship, tasks were relatively sparse, so I asked if I could join the Product team’s meetings to broaden my learning beyond technical aspects. This initiative led to my assignment of developing a new landing website for Sentient.io, which is currently the site you see when you visit Sentient’s webpage.
Overview: Zooming Out
My time at Sentient.io has been chaotic… but fulfilling. As you can tell, I had the opportunity to work on many projects and was well-supported in terms of resources. However, I’m slightly disappointed by the lack of mentorship, especially when I am in the phase of my journey where proper guidance would have been very handy.
Sentient.io gave me a glimpse into a later-stage startup. MatcHub, the first company I interned at as a Software Engineer, was a very young startup (around 9–10 months old when I first joined). Most of the employees at MatcHub were super motivated, and there was a fresh energy in the startup. In fact, most, if not all, of the employees were either interns or fresh graduates with less than two years of working experience. Sentient.io, on the other hand, had seasoned veterans with substantial experience in the industry. It is also successful in raising funds and is a Series B company that was founded in 2017. Hence, the energy at Sentient.io was very different, as I think people were a lot more experienced, less idealistic, and more realistic.
That being said, both companies shared the same innovative spirit — being willing to try out new things. Sentient.io’s CEO is a great example, always pushing the interns to try out new proof-of-concept products and providing us with the necessary resources efficiently.
Conclusion
I officially ended my internship in July, completing a 3-month internship that started in May. Looking back, I am extremely grateful for my time there. I made good colleagues who turned into friends and learned a ton during that time. I even managed to complete an AWS Solution Architect Associate certificate nearing the end of my internship. Most importantly, I had the chance to work on several backend technologies and get exposed to even more. I also gained a better understanding of how more established companies function. It was an enriching summer for sure!
And off I went, to my best year in university — my penultimate year :)