Joanna fine-tuned a 27B AI model on the HP ZBook Ultra G1a using examples of her own edits. The laptop could do the training. The harder question was whether the model would learn when to change her writing—and when to leave it alone.

Estimated reading time: 16–18 minutes

 

When HP let me keep the ZBook Ultra G1a after my review, their PR team said they knew I would put it to good use.

They were right. What they had really done was give my local-AI obsession a permanent sandbox.

What started as a review unit has since become the machine I keep reaching for whenever I want to poke at local AI. By the time I finished the original ZBook article, I had already used it for local inference, RAG, automation, agents and several experiments involving the NPU.

The point of that review was that once the hardware became capable enough, simply running the model stopped being the interesting part. The harder questions were everything that came afterwards.

I had been wanting to learn more about fine-tuning for a while, and Unsloth Studio appeared at a convenient moment. It promised a more approachable way into model training, while the ZBook already had 64GB of unified memory sitting on my desk waiting to be abused in the name of curiosity.

The obvious first experiment was to train a small model on a generic dataset, confirm that nothing caught fire and call the exercise a success. I did start there, but proving that training worked was only going to keep me entertained for so long.

If I was going to learn how to train a model, I wanted to give it a job I actually cared about.

I write a lot. More importantly for this experiment, I also edit myself a lot. Over years of writing reviews I have accumulated rough drafts, half-finished thoughts, revisions and final published copy, with fairly consistent patterns in what happens between them. I cut repetition, tighten technical claims, preserve uncertainty where the evidence does not justify certainty, and remove language that sounds too polished, too generic or too much like marketing copy.

And, occasionally, I leave the stupid joke alone because the stupid joke was fine.

Which gave me a much more interesting question than whether the ZBook could simply train a model:

Could I train a local model to edit my writing more like I do?

And what would it actually take to do that on a laptop?

Getting Unsloth running

The first attempt did not inspire enormous confidence.

The Unsloth Studio desktop installer failed almost immediately because it tried to access a path containing a literal $HOME:

\\?\$HOME\AppData\Local\Unsloth Studio (Desktop)\install.ps1

A literal $HOME was not especially useful to Windows.

Unsloth also publishes a standalone PowerShell installation method:

irm https://unsloth.ai/install.ps1 | iex

That worked, and more interestingly, it correctly identified the ZBook’s integrated AMD Radeon 8050S as gfx1151 and selected Unsloth’s AMD/ROCm installation path automatically.

So while the desktop installer itself felt beta, the hardware detection underneath it behaved far more confidently. After another fairly lengthy dependency setup on first launch, Studio was usable.

My first model was a 4-bit Qwen3-4B build. I trained it with QLoRA using the first 500 rows of the FineTome-100k dataset, a 2,048-token context and 30 training steps.

QLoRA keeps the underlying model weights frozen and trains a much smaller set of low-rank adapter weights instead, making this sort of fine-tuning far more practical on a laptop.

This first run was deliberately a smoke test rather than an attempt to produce a useful model.

The Radeon sat at roughly 95 to 100 percent Compute utilisation during training, while the NPU remained effectively idle. The run completed in 10 minutes and 44 seconds, processing 132,376 tokens, with training loss falling to 0.5274 by the final step.

There was no evaluation split, so that number did not tell me whether the resulting model had become better. It established something more basic: the local training pipeline worked, on an AMD laptop, and the GPU was doing the heavy lifting.

Training also brought back one of the more confusing parts of my original ZBook testing. Windows reports roughly 15.8GB as Dedicated GPU memory and up to 31.8GB as Shared GPU memory on this machine, but the ZBook uses unified physical memory. These are accounting categories, not two separate banks of VRAM and system RAM.

During the 4B run, Task Manager-reported GPU memory rose from around 18.4GB to 21.8GB, including memory accounted under the Shared category. The useful point is simply that the workload was not confined to the approximately 16GB BIOS-reserved Dedicated GPU memory allocation. It could make use of more of the unified pool.

That would matter a lot more once the model got bigger.

Teaching it something I actually wanted

Once the FineTome run was complete, I compared the Qwen3-4B base model with the FineTome-tuned version using three short editing passages, each testing a different editorial tendency.

One deliberately contained uncertainty. The source said the laptop did seem faster, but also made clear that I had changed more than one thing and could not attribute the result to the memory setting alone. The FineTome-tuned model remained cautious overall, but subtly strengthened the observation before qualifying it afterwards.

That is a small wording change, but editorially it matters.

Another test passage came from a Narwal Freo 20 incident under my coffee table. The version that made it into my test material was much more sanded down than the original account.

The real event was more entertaining.

After about a minute and 22 seconds, the Freo 20 investigated the low support rail, apparently decided to go for it, launched itself over and landed with a thud underneath the table. It startled me. Having successfully entered Coffee Table Prison, it then happily drove around in circles with no apparent way back out until I lifted it free.

It subsequently waddled back to its dock.

Even in simplified form, the test passage still gave the models plenty of opportunity to embellish it. The base model became enthusiastic, adding flourishes such as “somehow managed to crawl” and “utterly committed to its error”. None of it was disastrous, but none of it was mine either. The FineTome version was much more restrained.

Then I gave both models copy that was already working. The base model still found things to change. The FineTome model effectively left it alone.

That was the point where the experiment became much more interesting. Fine-tuning had changed the model’s editorial tendencies.

The next question was whether I could steer those tendencies deliberately.

The goal was not to make a model that could broadly “write like me”. That is vague, difficult to evaluate and far too easy to turn into an imitation exercise.

I wanted something narrower:

Could I train a model to edit rough review copy towards the way I actually edit it myself?

That made provenance important.

The useful training examples were not simply paragraphs I had written. They were transformations: an earlier version and the version I eventually chose.

Illustration of rough writing, editing notes and approved copy becoming a training pair.
Building the training data from draft-to-final editing decisions.

 

Sometimes the change was substantial. Sometimes it meant tightening speech-to-text rambling, improving rhythm or making a technical explanation easier to read. Sometimes it meant preserving an uncertainty that would have been easy to accidentally polish away.

And sometimes the useful lesson was that the original was already fine.

For both 27B experiments, I kept training, validation and final evaluation separate. Each adapter used 20 training examples and three held-out validation examples. For charm-v1, those three validation examples all came from an Orbi review, with no Orbi material included in training. The behavioural test passages sat outside both sets. For the final already-working test, I went one step further and used copy from my Elegear mattress-pad review, a project that had appeared nowhere in training or validation.

The training instruction was:

Edit the following review copy into Joanna’s editorial voice. Preserve factual meaning, uncertainty, technical accuracy and humour. Improve clarity, flow and specificity without inventing new claims or observations. If the copy is already working, make only the changes that are actually needed.

That last sentence became particularly important.

A useful editor should know when to stop editing.

Auto had ideas

Moving from the 4B experiment to Qwen3.8-27B introduced another problem.

Initially, the 27B GGUF inference file failed to initialise in Unsloth with a Vulkan out-of-memory error. That looked worryingly familiar. My previous ZBook investigation had already shown that software changes could alter the practical model limits of exactly the same hardware.

This time, however, the model itself was not the problem.

The same GGUF inference file worked in Ollama with CPU-only operation, partial GPU offload, automatic GPU offload and a 16,384-token context.

Context settings of 65,536 and 131,072 tokens fit, while Auto selected 262,144 tokens and failed.
The context choices and memory estimates observed in Unsloth Studio. Illustration based on my actual testing.

 

The culprit turned out to be much more mundane.

Unsloth’s Auto context setting had quietly selected the model’s full 262,144-token context.

I did not.

At that setting, Unsloth’s shared-memory estimate rose to around 39.5GiB, including nearly 19GiB of KV cache, and the model failed to initialise.

Once I selected the context explicitly, the picture changed.

At 65,536 tokens, Unsloth estimated 26.37GiB shared, including 6.92GiB of KV cache. At 131,072 tokens, that increased to 30.74GiB shared and 10.92GiB of KV cache.

Both worked.

So the useful conclusion was not that Vulkan could not run the model or that 27B simply did not fit.

The failure depended on configuration.

Once again, the software stack was helping define the practical hardware limit.

Training the first 27B adapter

For fine-tuning, I used Unsloth’s 4-bit Qwen3.8-27B training build rather than the GGUF inference file I had been testing above.

My first adapter was deliberately about restraint.

I called it restraint-v1, although conceptually its job was simpler:

Don’t make my writing worse.

I used 20 training examples, three validation examples, three epochs and 30 steps. QLoRA was configured at 4-bit with a LoRA rank and alpha of 32, a learning rate of 2e-4, batch size 1 and gradient accumulation of 2, giving an effective batch size of 2. Context was 2,048 tokens.

The first attempt made it considerably further before Windows found a different way to object: error 1455, because my paging file was far too small.

Windows had an initial allocation of only 600MB and a maximum of 4GB.

I returned pagefile management to automatic and ran exactly the same configuration again.

This time the run completed in 13 minutes and 44 seconds. The Radeon sat around 94 to 95 percent Compute utilisation, while Task Manager-reported GPU memory reached roughly 28GB.

The training run proved that I could fine-tune the 27B model locally. What mattered more was whether 20 examples had actually changed how it edited.

The Qwen3.8-27B base model was already a much better editor than the 4B model, so this was a harder test.

On a technical-uncertainty passage, both preserved the caveat, although restraint-v1 stayed slightly closer to my source wording. On the same simplified Narwal passage, the base 27B was already much less inclined to embellish the joke than the smaller model had been.

The early comparisons suggested a shift towards restraint, but there were too few of them to tell me whether that behaviour would hold up.

Restraint was only half the job

There was still a problem.

My final writing is not simply rough writing with fewer unnecessary edits.

Sometimes I deliberately reshape a sentence. Sometimes a technical explanation needs rhythm as well as accuracy. Sometimes speech-to-text needs rescuing from itself. Sometimes the useful part of a review is the lived observation surrounding the specification.

Restraint-v1 was learning what not to damage.

I wanted a second adapter that could also learn what I tended to add.

Editorial illustration of restraint-v1 and charm-v1 as separate editing approaches, with Trevor the lobster between them.

Charm is not a permission model

A certain lobster had already taught me one useful lesson in the original ZBook review: charm is not a permission model.

Charm does, however, make the reading experience considerably more pleasant.

For the second dataset, I concentrated on examples involving rhythm, lived experience, specificity, technical readability, de-polishing, ramble reduction and the occasional dry line that worked because nobody explained it afterwards.

I called the adapter charm-v1.

Its job was not “add jokes”. It was closer to:

Make the material better without ceasing to sound like me.

Charm-v1 started again from the untouched Qwen3.8-27B base model. It was not trained on top of restraint-v1, which meant the two adapters remained separate experiments from the same starting point.

Finding possible examples was easy.

Deciding which ones actually deserved to become training signal was harder.

I accumulated 42 candidates from several review projects. Some contained weak transformations, duplicated stronger examples or mixed stylistic edits with factual corrections that were difficult to separate cleanly. I excluded them from this first clean set.

The final charm-v1 training file contained 20 examples: six from Laifen, six from Edifier, six from the ZBook review and two from MOVA. Eighteen were ordinary draft-to-final transformations from my own writing. The two MOVA examples began as my own rough speech-to-text or notes and ended as final prose I had approved for use.

One of the last examples to earn a place came from my MOVA material.

My original speech-to-text note was:

so exactly what you highlighted – my sister-in-law has affectionately named their home robot Bob – when I got there, things had been moved, so Bob could do his job

The training target became:

At my sister-in-law’s place in Sydney, their robot vacuum has affectionately been named Bob. When I arrived, things had been shifted out of Bob’s way so he could do his job.

Fair point, MOVA.

The factual content stayed intact, the ramble disappeared, the lived observation became clearer, and the final line worked precisely because it did not explain itself.

Bob was hired at the eleventh hour, and then I stopped changing the dataset before I found another shiny thing.

Training charm-v1

Charm-v1 used the same overall QLoRA configuration as restraint-v1.

Its 30-step run completed in 13 minutes and 25 seconds, remarkably close to the earlier 13:44 result.

It processed 15,621 tokens, compared with 10,629 for restraint-v1 despite both datasets containing 20 examples.

That difference matters when looking at final training losses. These were not equivalent workloads, so a lower final loss does not mean one adapter trained “better” than the other.

Charm-v1 also pushed the unified-memory system harder.

GPU Compute generally sat between 90 and 96 percent, with temperatures around 76 to 78°C. Task Manager-reported GPU memory climbed from around 28GB early in training to 31GB near the end, with the highest value I saw live at approximately 31.2GB.

At that point Task Manager showed around 15.4GB under Dedicated GPU memory and another 15.6GB under Shared.

Unsloth Studio preparing the model beside Windows Task Manager showing GPU memory and NPU activity.
Unsloth Studio and Task Manager during model preparation.

 

Both 27B runs also produced an interesting validation pattern. Training loss continued down, while validation loss reached its lowest point around the middle of training and then began rising again.

Four Unsloth charts for charm-v1: training loss, gradient norm, learning rate and evaluation loss.
Charm-v1 training loss continued to fall while evaluation loss reached its lowest point around the middle of the run before rising again. Three validation examples are too few to draw a firm conclusion.

 

Charm-v1 made the shape particularly obvious, falling from roughly 1.27 to around 1.16 before climbing back towards 1.30.

Each adapter had only three validation examples, and all three charm-v1 examples came from one Orbi article, so I would not read too much into that shape.

What it does raise is a useful question: were three epochs already more than these tiny datasets needed?

That is something a larger dataset and stronger validation set would be much better equipped to answer.

Did the adapters actually change the model?

There is an obvious limitation here: I was training the model towards my own editing decisions, and I was also the person judging whether it got closer.

That is difficult to avoid when the thing being tested is partly my own editorial judgement.

Illustrated side-by-side comparison of base and fine-tuned model edits to a technical-uncertainty passage.
An editorial presentation of the actual comparison outputs, with the changed wording highlighted.

 

The most useful test turned out to be an already-working passage from my Elegear mattress-pad review, a project that had appeared nowhere in training or validation.

The source was:

So while I wait for Melbourne to cooperate, I’ve decided to make the timing work. I already have an electric blanket, which gives me a repeatable source of heat directly underneath the mattress pad. It isn’t a perfect recreation of a 35-degree summer night, obviously, but it should tell me more than simply lying on the pad in cool spring weather and declaring that yes, it feels cool.

The base 27B still found several things to polish.

It removed the opening “So”, changed “make the timing work” to “make the best of the timing”, changed “It isn’t” to “It’s not”, and reformatted the final line.

restraint-v1 returned the passage unchanged.

Charm-v1 changed one thing:

“underneath the mattress pad” -> “underneath the pad”

Everything else remained intact, including the caveat that the electric blanket was not a perfect recreation of a hot summer night and the slightly self-aware ending about declaring that yes, it feels cool.

One unseen passage cannot tell me how reliably either adapter will behave, but it does show that the selectivity was not limited to projects represented in training.

There was still another possibility to rule out.

Perhaps charm-v1 had learned to barely edit.

A separate unpublished passage from a running draft answered that.

The source was:

The setup was mostly easy, though I did manage to miss one setting the first time and then wondered why it wasn’t doing what I expected. Once I went back and fixed it, it was fine. I don’t think the interface is actually confusing so much as it assumes you’re paying slightly more attention than I apparently was at the time. After that, I didn’t have any other problems and didn’t need to go looking through the manual again.

Charm-v1 returned:

The setup was mostly straightforward, although I did manage to miss one setting the first time and then wondered why it wasn’t doing what I expected. Once I went back and fixed it, everything was fine. I don’t think the interface is actually confusing so much as it assumes you’re paying slightly more attention than I apparently was at the time. After that, I didn’t have any further issues and didn’t need to reach for the manual again.

So charm-v1 was still willing to make several edits.

I would not call every change an improvement.

“Straightforward” is a word I regularly cut from my own writing, and “further issues” was more polished and generic than “other problems”.

That is useful evidence too.

The experiment was not producing a finished editor after 20 examples.

It was producing behavioural shifts worth investigating.

Comparing 27B models became part of the test

The comparison workflow exposed another practical limitation.

With the smaller models, Compare had kept both loaded and available. With the 27B base model and charm-v1, Studio instead loaded and generated from them sequentially.

I couldn’t establish whether that change was caused by memory pressure at this size or by some other behaviour in Compare mode.

With each swap taking long enough to notice, the “Un” in Unsloth was starting to feel slightly aspirational.

There was also an avoidable inefficiency. After Model 2 finished and remained loaded, submitting another comparison still caused Studio to reload Model 1 first, generate its answer, then load Model 2 again.

Starting with whichever model was already resident would save one model load on each subsequent comparison.

With smaller models that may barely matter.

With these, it did.

The Elegear test also reinforced another point about performance.

All three models received the same 796-token prompt. Studio reported 3,969 output tokens for the base model, 1,690 for restraint-v1 and 1,511 for charm-v1.

I did not have a separate visible-answer versus reasoning-token breakdown, so I would not treat those figures as a direct measure of verbosity.

The counts help explain why response time could diverge from raw generation rate: producing considerably more tokens can make a response take longer overall.

This was not a formal speed benchmark, but it was a useful reminder that tokens per second only tells part of the story.

So, can I train a laptop to edit like me?

Not from 20 examples.

But I can train a 27B model locally on a laptop using a dataset built from my own editing history, and the test passages showed that fine-tuning could shift how the model approached the task.

Restraint-v1 was less inclined to rewrite copy simply because it could.

Charm-v1 showed some of the same selectivity while still being willing to edit, although not every edit was one I would keep.

That does not make either adapter a finished editing model.

It makes them useful experiments.

More importantly, the work around the models became at least as interesting as the training itself.

Choosing the data mattered. Separating factual corrections from stylistic ones mattered. Keeping evaluation material out of the training set mattered. Defaults such as a 262,144-token Auto context mattered. Windows’ pagefile mattered. Unified-memory behaviour mattered. Once two large models had to be compared, even the order in which Studio loaded them mattered.

Unsloth Studio made the mechanics of local fine-tuning dramatically more approachable than building the entire pipeline manually, even if it still feels beta in places.

None of those rough edges stopped the experiment.

If anything, they reinforced the lesson I took away from the original ZBook review.

The hardware was capable of running the workload.

The interesting problems increasingly lived around it.

I started this experiment wanting to know whether I could train a laptop to edit more like me.

The answer is not yet “yes”.

But it is considerably more interesting than “no”.

 

Disclosure

HP originally supplied the ZBook Ultra G1a as a review unit and later allowed me to keep it. HP had no editorial input into this article. Unsloth was not involved in the testing or editorial process.

Related: HP ZBook Ultra G1a 14 Review: The Hardware Was the Easy Part